зеркало из https://github.com/Azure/DotNetty.git
Motivation:
enable netty's internal logging experience to ease porting efforts and streamline logging configuration Modifications: - ported over InternalLogger and InternalLoggerFactory - implemented InternalLogger using EventSource - switched existing internal logging to this (increasing parity with netty) - added logging configuration in Echo example - added log to xunit output to end-to-end tests *** extras - fixed Echo client to send back received message (not 0 bytes) - MqttDecoder no longer closes the Channel by itself instead changing internal state to invalid and forwarding an exception. - further fix to ReSharper's code cleanup settings to properly arrange scope modifiers Result: internal components can use familiar experience to perform logging, e.g. `static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<AbstractChannel>();`
This commit is contained in:
Родитель
39aa6547bc
Коммит
0722ade2a8
|
@ -20,7 +20,7 @@
|
|||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FElsewhere/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">WARNING</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseObjectOrCollectionInitializer/@EntryIndexedValue">HINT</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Simple/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="Simple"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>IMPLICIT_EXCEPT_PRIMITIVE_TYPES</ForeachVariableStyle></CSUseVar><CSUpdateFileHeader>True</CSUpdateFileHeader><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>ReplaceAll</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><CSShortenReferences>True</CSShortenReferences><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CSArrangeQualifiers>True</CSArrangeQualifiers><CSEnforceVarKeywordUsageSettings>True</CSEnforceVarKeywordUsageSettings><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSharpFormatDocComments>True</CSharpFormatDocComments></Profile></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Simple/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="Simple"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>IMPLICIT_EXCEPT_PRIMITIVE_TYPES</ForeachVariableStyle></CSUseVar><CSUpdateFileHeader>True</CSUpdateFileHeader><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>ReplaceAll</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><CSShortenReferences>True</CSShortenReferences><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CSArrangeQualifiers>True</CSArrangeQualifiers><CSEnforceVarKeywordUsageSettings>True</CSEnforceVarKeywordUsageSettings><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSharpFormatDocComments>True</CSharpFormatDocComments><CSArrangeTypeModifiers>True</CSArrangeTypeModifiers><CSArrangeTypeMemberModifiers>True</CSArrangeTypeMemberModifiers><CSSortModifiers>True</CSSortModifiers></Profile></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Simple</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">Simple</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/DEFAULT_INTERNAL_MODIFIER/@EntryValue">Implicit</s:String>
|
||||
|
|
|
@ -32,6 +32,14 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Practices.EnterpriseLibrary.SemanticLogging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\EnterpriseLibrary.SemanticLogging.2.0.1406.1\lib\net45\Microsoft.Practices.EnterpriseLibrary.SemanticLogging.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
|
@ -48,6 +56,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\DotNetty.Buffers\DotNetty.Buffers.csproj">
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace Echo.Client
|
|||
if (byteBuffer != null)
|
||||
{
|
||||
this.buffer.Initialize();
|
||||
byteBuffer.ReadBytes(this.buffer, 0, byteBuffer.ReadableBytes);
|
||||
byteBuffer.Duplicate().ReadBytes(this.buffer, 0, byteBuffer.ReadableBytes);
|
||||
string msg = Encoding.UTF8.GetString(this.buffer);
|
||||
Console.WriteLine("Received from server: " + msg);
|
||||
}
|
||||
|
|
|
@ -4,19 +4,27 @@
|
|||
namespace Echo.Client
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Handlers.Tls;
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
|
||||
using Microsoft.Practices.EnterpriseLibrary.SemanticLogging;
|
||||
|
||||
class Program
|
||||
{
|
||||
static async Task RunClient()
|
||||
{
|
||||
var eventListener = new ObservableEventListener();
|
||||
eventListener.LogToConsole();
|
||||
eventListener.EnableEvents(DefaultEventSource.Log, EventLevel.Verbose);
|
||||
|
||||
var group = new MultithreadEventLoopGroup();
|
||||
|
||||
try
|
||||
{
|
||||
var bootstrap = new Bootstrap();
|
||||
|
@ -47,6 +55,7 @@ namespace Echo.Client
|
|||
finally
|
||||
{
|
||||
group.ShutdownGracefullyAsync().Wait(1000);
|
||||
eventListener.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="EnterpriseLibrary.SemanticLogging" version="2.0.1406.1" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net45" />
|
||||
</packages>
|
|
@ -32,6 +32,14 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Practices.EnterpriseLibrary.SemanticLogging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\EnterpriseLibrary.SemanticLogging.2.0.1406.1\lib\net45\Microsoft.Practices.EnterpriseLibrary.SemanticLogging.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.5.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Core" />
|
||||
|
@ -48,6 +56,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\DotNetty.Buffers\DotNetty.Buffers.csproj">
|
||||
|
|
|
@ -4,17 +4,24 @@
|
|||
namespace Echo.Server
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Handlers.Tls;
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
|
||||
using Microsoft.Practices.EnterpriseLibrary.SemanticLogging;
|
||||
|
||||
class Program
|
||||
{
|
||||
static async Task RunServer()
|
||||
{
|
||||
var eventListener = new ObservableEventListener();
|
||||
eventListener.LogToConsole();
|
||||
eventListener.EnableEvents(DefaultEventSource.Log, EventLevel.Verbose);
|
||||
|
||||
var bossGroup = new MultithreadEventLoopGroup(1);
|
||||
var workerGroup = new MultithreadEventLoopGroup();
|
||||
try
|
||||
|
@ -45,6 +52,7 @@ namespace Echo.Server
|
|||
finally
|
||||
{
|
||||
Task.WaitAll(bossGroup.ShutdownGracefullyAsync(), workerGroup.ShutdownGracefullyAsync());
|
||||
eventListener.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="EnterpriseLibrary.SemanticLogging" version="2.0.1406.1" targetFramework="net45" />
|
||||
<package id="Newtonsoft.Json" version="5.0.8" targetFramework="net45" />
|
||||
</packages>
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
namespace DotNetty.Buffers
|
||||
{
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using DotNetty.Common;
|
||||
|
||||
|
@ -22,12 +21,6 @@ namespace DotNetty.Buffers
|
|||
false); // todo: prepare
|
||||
}
|
||||
|
||||
[Conditional("TRACE")]
|
||||
public void LogUsage()
|
||||
{
|
||||
this.pool.LogUsage("pooled buffers available");
|
||||
}
|
||||
|
||||
public int MaxPooledBufSize { get; private set; }
|
||||
|
||||
protected override IByteBuffer NewBuffer(int initialCapacity, int maxCapacity)
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
<Link>Properties\SharedAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\Friends.cs" />
|
||||
<Compile Include="MqttEventSource.cs" />
|
||||
<Compile Include="MqttDecoder.cs" />
|
||||
<Compile Include="MqttEncoder.cs" />
|
||||
<Compile Include="Packets\ConnAckPacket.cs" />
|
||||
|
|
|
@ -46,10 +46,6 @@ namespace DotNetty.Codecs.Mqtt
|
|||
|
||||
output.Add(packet);
|
||||
this.Checkpoint();
|
||||
if (MqttEventSource.Log.IsVerboseEnabled)
|
||||
{
|
||||
MqttEventSource.Log.Verbose("Decoded packet.", packet.ToString());
|
||||
}
|
||||
break;
|
||||
case ParseState.Failed:
|
||||
// read out data until connection is closed
|
||||
|
@ -59,16 +55,11 @@ namespace DotNetty.Codecs.Mqtt
|
|||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
catch (DecoderException ex)
|
||||
catch (DecoderException)
|
||||
{
|
||||
input.SkipBytes(input.ReadableBytes);
|
||||
this.Checkpoint(ParseState.Failed);
|
||||
if (MqttEventSource.Log.IsErrorEnabled)
|
||||
{
|
||||
MqttEventSource.Log.Error("Exception while decoding.", ex);
|
||||
}
|
||||
|
||||
this.CloseAsync(context);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,11 +21,6 @@ namespace DotNetty.Codecs.Mqtt
|
|||
protected override void Encode(IChannelHandlerContext context, Packet message, List<object> output)
|
||||
{
|
||||
DoEncode(context.Allocator, message, output);
|
||||
|
||||
if (MqttEventSource.Log.IsVerboseEnabled)
|
||||
{
|
||||
MqttEventSource.Log.Verbose("Encoded packet.", message.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsSharable
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Codecs.Mqtt
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
|
||||
[EventSource(Name = "DotNetty-Mqtt")]
|
||||
public class MqttEventSource : EventSource
|
||||
{
|
||||
const int VerboseEventId = 1;
|
||||
const int InfoEventId = 2;
|
||||
const int WarningEventId = 3;
|
||||
const int ErrorEventId = 4;
|
||||
|
||||
public static readonly MqttEventSource Log = new MqttEventSource();
|
||||
|
||||
MqttEventSource()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsVerboseEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Verbose, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsInfoEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Informational, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsWarningEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Warning, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsErrorEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Error, EventKeywords.None); }
|
||||
}
|
||||
|
||||
[Event(VerboseEventId, Level = EventLevel.Verbose)]
|
||||
public void Verbose(string message, string info)
|
||||
{
|
||||
if (this.IsVerboseEnabled)
|
||||
{
|
||||
this.WriteEvent(VerboseEventId, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[Event(InfoEventId, Level = EventLevel.Informational)]
|
||||
public void Info(string message, string info)
|
||||
{
|
||||
if (this.IsInfoEnabled)
|
||||
{
|
||||
this.WriteEvent(InfoEventId, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string message)
|
||||
{
|
||||
this.Warning(message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string message, Exception exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.Warning(message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(WarningEventId, Level = EventLevel.Warning)]
|
||||
public void Warning(string message, string exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.WriteEvent(WarningEventId, message, exception);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Error(string message, Exception exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.Error(message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(ErrorEventId, Level = EventLevel.Error)]
|
||||
public void Error(string message, string exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.WriteEvent(ErrorEventId, message, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Concurrency
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
|
||||
[EventSource(Name = "DotNetty-Executor")]
|
||||
public class ExecutorEventSource : EventSource
|
||||
{
|
||||
const int VerboseEventId = 1;
|
||||
const int InfoEventId = 2;
|
||||
const int WarningEventId = 3;
|
||||
const int ErrorEventId = 4;
|
||||
|
||||
public static readonly ExecutorEventSource Log = new ExecutorEventSource();
|
||||
|
||||
ExecutorEventSource()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsVerboseEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Verbose, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsInfoEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Informational, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsWarningEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Warning, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsErrorEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Error, EventKeywords.None); }
|
||||
}
|
||||
|
||||
[Event(VerboseEventId, Level = EventLevel.Verbose)]
|
||||
public void Verbose(string message, string info)
|
||||
{
|
||||
if (this.IsVerboseEnabled)
|
||||
{
|
||||
this.WriteEvent(VerboseEventId, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[Event(InfoEventId, Level = EventLevel.Informational)]
|
||||
public void Info(string message, string info)
|
||||
{
|
||||
if (this.IsInfoEnabled)
|
||||
{
|
||||
this.WriteEvent(InfoEventId, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string message)
|
||||
{
|
||||
this.Warning(message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string message, Exception exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.Warning(message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(WarningEventId, Level = EventLevel.Warning)]
|
||||
public void Warning(string message, string exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.WriteEvent(WarningEventId, message, exception);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Error(string message, Exception exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.Error(message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(ErrorEventId, Level = EventLevel.Error)]
|
||||
public void Error(string message, string exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.WriteEvent(ErrorEventId, message, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
namespace DotNetty.Common.Concurrency
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ namespace DotNetty.Common.Concurrency
|
|||
using System.Diagnostics.Contracts;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Common.Utilities;
|
||||
|
||||
public class SingleThreadEventExecutor : IEventExecutor
|
||||
|
@ -21,6 +22,9 @@ namespace DotNetty.Common.Concurrency
|
|||
const int ST_TERMINATED = 5;
|
||||
const string DefaultWorkerThreadName = "SingleThreadEventExecutor worker";
|
||||
|
||||
static readonly IInternalLogger Logger =
|
||||
InternalLoggerFactory.GetInstance<SingleThreadEventExecutor>();
|
||||
|
||||
static readonly Action<object> DelegatingAction = action => ((Action)action)();
|
||||
static readonly TimeSpan DefaultShutdownQuietPeriod = TimeSpan.FromSeconds(2);
|
||||
static readonly TimeSpan DefaultShutdownTimeout = TimeSpan.FromSeconds(15);
|
||||
|
@ -349,11 +353,10 @@ namespace DotNetty.Common.Concurrency
|
|||
// Check if confirmShutdown() was called at the end of the loop.
|
||||
if (success && this.gracefulShutdownStartTime == PreciseTimeSpan.Zero)
|
||||
{
|
||||
ExecutorEventSource.Log.Error(
|
||||
Logger.Error(
|
||||
string.Format("Buggy {0} implementation; {1}.ConfirmShutdown() must be called " + "before run() implementation terminates.",
|
||||
typeof(IEventExecutor).Name,
|
||||
typeof(SingleThreadEventExecutor).Name),
|
||||
(string)null);
|
||||
typeof(SingleThreadEventExecutor).Name));
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -378,7 +381,7 @@ namespace DotNetty.Common.Concurrency
|
|||
Interlocked.Exchange(ref this.executionState, ST_TERMINATED);
|
||||
if (!this.taskQueue.IsEmpty)
|
||||
{
|
||||
ExecutorEventSource.Log.Warning(string.Format("An event executor terminated with non-empty task queue ({0})", this.taskQueue.Count));
|
||||
Logger.Warn(string.Format("An event executor terminated with non-empty task queue ({0})", this.taskQueue.Count));
|
||||
}
|
||||
|
||||
//firstRun = true;
|
||||
|
@ -456,7 +459,7 @@ namespace DotNetty.Common.Concurrency
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExecutorEventSource.Log.Warning("A task raised an exception.", ex);
|
||||
Logger.Warn("A task raised an exception.", ex);
|
||||
}
|
||||
|
||||
task = this.PollTask();
|
||||
|
@ -488,7 +491,7 @@ namespace DotNetty.Common.Concurrency
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ExecutorEventSource.Log.Warning("A task raised an exception.", ex);
|
||||
Logger.Warn("A task raised an exception.", ex);
|
||||
}
|
||||
|
||||
runTasks++;
|
||||
|
@ -677,7 +680,10 @@ namespace DotNetty.Common.Concurrency
|
|||
|
||||
int IComparable<IScheduledRunnable>.CompareTo(IScheduledRunnable other)
|
||||
{
|
||||
Contract.Requires(other != null);
|
||||
if (other == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return this.Deadline.CompareTo(other.Deadline);
|
||||
}
|
||||
|
@ -718,7 +724,10 @@ namespace DotNetty.Common.Concurrency
|
|||
|
||||
int IComparable<IScheduledRunnable>.CompareTo(IScheduledRunnable other)
|
||||
{
|
||||
Contract.Requires(other != null);
|
||||
if (other == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return this.Deadline.CompareTo(other.Deadline);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<AssemblyName>DotNetty.Common</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<CodeContractsAssemblyMode>0</CodeContractsAssemblyMode>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -20,6 +21,49 @@
|
|||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
|
||||
<CodeContractsRuntimeOnlyPublicSurface>True</CodeContractsRuntimeOnlyPublicSurface>
|
||||
<CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
|
||||
<CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
|
||||
<CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
|
||||
<CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
|
||||
<CodeContractsNonNullObligations>True</CodeContractsNonNullObligations>
|
||||
<CodeContractsBoundsObligations>True</CodeContractsBoundsObligations>
|
||||
<CodeContractsArithmeticObligations>True</CodeContractsArithmeticObligations>
|
||||
<CodeContractsEnumObligations>True</CodeContractsEnumObligations>
|
||||
<CodeContractsRedundantAssumptions>True</CodeContractsRedundantAssumptions>
|
||||
<CodeContractsAssertsToContractsCheckBox>True</CodeContractsAssertsToContractsCheckBox>
|
||||
<CodeContractsRedundantTests>True</CodeContractsRedundantTests>
|
||||
<CodeContractsMissingPublicRequiresAsWarnings>True</CodeContractsMissingPublicRequiresAsWarnings>
|
||||
<CodeContractsMissingPublicEnsuresAsWarnings>False</CodeContractsMissingPublicEnsuresAsWarnings>
|
||||
<CodeContractsInferRequires>True</CodeContractsInferRequires>
|
||||
<CodeContractsInferEnsures>False</CodeContractsInferEnsures>
|
||||
<CodeContractsInferEnsuresAutoProperties>True</CodeContractsInferEnsuresAutoProperties>
|
||||
<CodeContractsInferObjectInvariants>False</CodeContractsInferObjectInvariants>
|
||||
<CodeContractsSuggestAssumptions>False</CodeContractsSuggestAssumptions>
|
||||
<CodeContractsSuggestAssumptionsForCallees>False</CodeContractsSuggestAssumptionsForCallees>
|
||||
<CodeContractsSuggestRequires>False</CodeContractsSuggestRequires>
|
||||
<CodeContractsNecessaryEnsures>True</CodeContractsNecessaryEnsures>
|
||||
<CodeContractsSuggestObjectInvariants>False</CodeContractsSuggestObjectInvariants>
|
||||
<CodeContractsSuggestReadonly>True</CodeContractsSuggestReadonly>
|
||||
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
|
||||
<CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
|
||||
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
|
||||
<CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
|
||||
<CodeContractsCustomRewriterAssembly />
|
||||
<CodeContractsCustomRewriterClass />
|
||||
<CodeContractsLibPaths />
|
||||
<CodeContractsExtraRewriteOptions />
|
||||
<CodeContractsExtraAnalysisOptions />
|
||||
<CodeContractsSQLServerOption />
|
||||
<CodeContractsBaseLineFile />
|
||||
<CodeContractsCacheAnalysisResults>True</CodeContractsCacheAnalysisResults>
|
||||
<CodeContractsSkipAnalysisIfCannotConnectToCache>False</CodeContractsSkipAnalysisIfCannotConnectToCache>
|
||||
<CodeContractsFailBuildOnWarnings>False</CodeContractsFailBuildOnWarnings>
|
||||
<CodeContractsBeingOptimisticOnExternal>True</CodeContractsBeingOptimisticOnExternal>
|
||||
<CodeContractsRuntimeCheckingLevel>Preconditions</CodeContractsRuntimeCheckingLevel>
|
||||
<CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
|
||||
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
|
@ -28,6 +72,49 @@
|
|||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
|
||||
<CodeContractsRuntimeOnlyPublicSurface>True</CodeContractsRuntimeOnlyPublicSurface>
|
||||
<CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
|
||||
<CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
|
||||
<CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
|
||||
<CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
|
||||
<CodeContractsNonNullObligations>True</CodeContractsNonNullObligations>
|
||||
<CodeContractsBoundsObligations>True</CodeContractsBoundsObligations>
|
||||
<CodeContractsArithmeticObligations>True</CodeContractsArithmeticObligations>
|
||||
<CodeContractsEnumObligations>True</CodeContractsEnumObligations>
|
||||
<CodeContractsRedundantAssumptions>True</CodeContractsRedundantAssumptions>
|
||||
<CodeContractsAssertsToContractsCheckBox>True</CodeContractsAssertsToContractsCheckBox>
|
||||
<CodeContractsRedundantTests>True</CodeContractsRedundantTests>
|
||||
<CodeContractsMissingPublicRequiresAsWarnings>True</CodeContractsMissingPublicRequiresAsWarnings>
|
||||
<CodeContractsMissingPublicEnsuresAsWarnings>False</CodeContractsMissingPublicEnsuresAsWarnings>
|
||||
<CodeContractsInferRequires>True</CodeContractsInferRequires>
|
||||
<CodeContractsInferEnsures>False</CodeContractsInferEnsures>
|
||||
<CodeContractsInferEnsuresAutoProperties>True</CodeContractsInferEnsuresAutoProperties>
|
||||
<CodeContractsInferObjectInvariants>False</CodeContractsInferObjectInvariants>
|
||||
<CodeContractsSuggestAssumptions>False</CodeContractsSuggestAssumptions>
|
||||
<CodeContractsSuggestAssumptionsForCallees>False</CodeContractsSuggestAssumptionsForCallees>
|
||||
<CodeContractsSuggestRequires>False</CodeContractsSuggestRequires>
|
||||
<CodeContractsNecessaryEnsures>True</CodeContractsNecessaryEnsures>
|
||||
<CodeContractsSuggestObjectInvariants>False</CodeContractsSuggestObjectInvariants>
|
||||
<CodeContractsSuggestReadonly>True</CodeContractsSuggestReadonly>
|
||||
<CodeContractsRunInBackground>True</CodeContractsRunInBackground>
|
||||
<CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
|
||||
<CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
|
||||
<CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
|
||||
<CodeContractsCustomRewriterAssembly />
|
||||
<CodeContractsCustomRewriterClass />
|
||||
<CodeContractsLibPaths />
|
||||
<CodeContractsExtraRewriteOptions />
|
||||
<CodeContractsExtraAnalysisOptions />
|
||||
<CodeContractsSQLServerOption />
|
||||
<CodeContractsBaseLineFile />
|
||||
<CodeContractsCacheAnalysisResults>True</CodeContractsCacheAnalysisResults>
|
||||
<CodeContractsSkipAnalysisIfCannotConnectToCache>False</CodeContractsSkipAnalysisIfCannotConnectToCache>
|
||||
<CodeContractsFailBuildOnWarnings>False</CodeContractsFailBuildOnWarnings>
|
||||
<CodeContractsBeingOptimisticOnExternal>True</CodeContractsBeingOptimisticOnExternal>
|
||||
<CodeContractsRuntimeCheckingLevel>Preconditions</CodeContractsRuntimeCheckingLevel>
|
||||
<CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
|
||||
<CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
|
@ -38,7 +125,7 @@
|
|||
<Compile Include="..\SharedAssemblyInfo.cs">
|
||||
<Link>Properties\SharedAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Concurrency\ExecutorEventSource.cs" />
|
||||
<Compile Include="Properties\Friends.cs" />
|
||||
<Compile Include="Concurrency\ExecutorTaskScheduler.cs" />
|
||||
<Compile Include="Concurrency\IEventExecutor.cs" />
|
||||
<Compile Include="Concurrency\IPausableEventExecutor.cs" />
|
||||
|
@ -46,6 +133,15 @@
|
|||
<Compile Include="Concurrency\IWrappedEventExecutor.cs" />
|
||||
<Compile Include="Concurrency\SingleThreadEventExecutor.cs" />
|
||||
<Compile Include="Concurrency\TaskCompletionSource.cs" />
|
||||
<Compile Include="Internal\Logging\AbstractInternalLogger.cs" />
|
||||
<Compile Include="Internal\Logging\DefaultEventSource.cs" />
|
||||
<Compile Include="Internal\Logging\EventSourceLogger.cs" />
|
||||
<Compile Include="Internal\Logging\EventSourceLoggerFactory.cs" />
|
||||
<Compile Include="Internal\Logging\FormattingTuple.cs" />
|
||||
<Compile Include="Internal\Logging\IInternalLogger.cs" />
|
||||
<Compile Include="Internal\Logging\InternalLoggerFactory.cs" />
|
||||
<Compile Include="Internal\Logging\InternalLogLevel.cs" />
|
||||
<Compile Include="Internal\Logging\MessageFormatter.cs" />
|
||||
<Compile Include="IReferenceCounted.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ThreadLocalObjectList.cs" />
|
||||
|
@ -62,6 +158,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="DotNetty.Common.nuspec" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// A skeletal implementation of {@link IInternalLogger}. This class implements
|
||||
/// all methods that have a { @link InternalLogLevel } parameter by default to call
|
||||
/// specific logger methods such as {@link #Info(String)} or {@link #isInfoEnabled()}.
|
||||
/// </summary>
|
||||
public abstract class AbstractInternalLogger : IInternalLogger
|
||||
{
|
||||
static readonly string EXCEPTION_MESSAGE = "Unexpected exception:";
|
||||
|
||||
readonly string name;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
protected AbstractInternalLogger(string name)
|
||||
{
|
||||
Contract.Requires(name != null);
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return this.name; }
|
||||
}
|
||||
|
||||
public bool IsEnabled(InternalLogLevel level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case InternalLogLevel.TRACE:
|
||||
return this.TraceEnabled;
|
||||
case InternalLogLevel.DEBUG:
|
||||
return this.DebugEnabled;
|
||||
case InternalLogLevel.INFO:
|
||||
return this.InfoEnabled;
|
||||
case InternalLogLevel.WARN:
|
||||
return this.WarnEnabled;
|
||||
case InternalLogLevel.ERROR:
|
||||
return this.ErrorEnabled;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract bool TraceEnabled { get; }
|
||||
|
||||
public abstract void Trace(string msg);
|
||||
|
||||
public abstract void Trace(string format, object arg);
|
||||
|
||||
public abstract void Trace(string format, object argA, object argB);
|
||||
|
||||
public abstract void Trace(string format, params object[] arguments);
|
||||
|
||||
public abstract void Trace(string msg, Exception t);
|
||||
|
||||
public void Trace(Exception t)
|
||||
{
|
||||
this.Trace(EXCEPTION_MESSAGE, t);
|
||||
}
|
||||
|
||||
public abstract bool DebugEnabled { get; }
|
||||
|
||||
public abstract void Debug(string msg);
|
||||
|
||||
public abstract void Debug(string format, object arg);
|
||||
|
||||
public abstract void Debug(string format, object argA, object argB);
|
||||
|
||||
public abstract void Debug(string format, params object[] arguments);
|
||||
|
||||
public abstract void Debug(string msg, Exception t);
|
||||
|
||||
public void Debug(Exception t)
|
||||
{
|
||||
this.Debug(EXCEPTION_MESSAGE, t);
|
||||
}
|
||||
|
||||
public abstract bool InfoEnabled { get; }
|
||||
|
||||
public abstract void Info(string msg);
|
||||
|
||||
public abstract void Info(string format, object arg);
|
||||
|
||||
public abstract void Info(string format, object argA, object argB);
|
||||
|
||||
public abstract void Info(string format, params object[] arguments);
|
||||
|
||||
public abstract void Info(string msg, Exception t);
|
||||
|
||||
public void Info(Exception t)
|
||||
{
|
||||
this.Info(EXCEPTION_MESSAGE, t);
|
||||
}
|
||||
|
||||
public abstract bool WarnEnabled { get; }
|
||||
|
||||
public abstract void Warn(string msg);
|
||||
|
||||
public abstract void Warn(string format, object arg);
|
||||
|
||||
public abstract void Warn(string format, params object[] arguments);
|
||||
|
||||
public abstract void Warn(string format, object argA, object argB);
|
||||
|
||||
public abstract void Warn(string msg, Exception t);
|
||||
|
||||
public void Warn(Exception t)
|
||||
{
|
||||
this.Warn(EXCEPTION_MESSAGE, t);
|
||||
}
|
||||
|
||||
public abstract bool ErrorEnabled { get; }
|
||||
|
||||
public abstract void Error(string msg);
|
||||
|
||||
public abstract void Error(string format, object arg);
|
||||
|
||||
public abstract void Error(string format, object argA, object argB);
|
||||
|
||||
public abstract void Error(string format, params object[] arguments);
|
||||
|
||||
public abstract void Error(string msg, Exception t);
|
||||
|
||||
public void Error(Exception t)
|
||||
{
|
||||
this.Error(EXCEPTION_MESSAGE, t);
|
||||
}
|
||||
|
||||
public void Log(InternalLogLevel level, string msg, Exception cause)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case InternalLogLevel.TRACE:
|
||||
this.Trace(msg, cause);
|
||||
break;
|
||||
case InternalLogLevel.DEBUG:
|
||||
this.Debug(msg, cause);
|
||||
break;
|
||||
case InternalLogLevel.INFO:
|
||||
this.Info(msg, cause);
|
||||
break;
|
||||
case InternalLogLevel.WARN:
|
||||
this.Warn(msg, cause);
|
||||
break;
|
||||
case InternalLogLevel.ERROR:
|
||||
this.Error(msg, cause);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(InternalLogLevel level, Exception cause)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case InternalLogLevel.TRACE:
|
||||
this.Trace(cause);
|
||||
break;
|
||||
case InternalLogLevel.DEBUG:
|
||||
this.Debug(cause);
|
||||
break;
|
||||
case InternalLogLevel.INFO:
|
||||
this.Info(cause);
|
||||
break;
|
||||
case InternalLogLevel.WARN:
|
||||
this.Warn(cause);
|
||||
break;
|
||||
case InternalLogLevel.ERROR:
|
||||
this.Error(cause);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(InternalLogLevel level, string msg)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case InternalLogLevel.TRACE:
|
||||
this.Trace(msg);
|
||||
break;
|
||||
case InternalLogLevel.DEBUG:
|
||||
this.Debug(msg);
|
||||
break;
|
||||
case InternalLogLevel.INFO:
|
||||
this.Info(msg);
|
||||
break;
|
||||
case InternalLogLevel.WARN:
|
||||
this.Warn(msg);
|
||||
break;
|
||||
case InternalLogLevel.ERROR:
|
||||
this.Error(msg);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(InternalLogLevel level, string format, object arg)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case InternalLogLevel.TRACE:
|
||||
this.Trace(format, arg);
|
||||
break;
|
||||
case InternalLogLevel.DEBUG:
|
||||
this.Debug(format, arg);
|
||||
break;
|
||||
case InternalLogLevel.INFO:
|
||||
this.Info(format, arg);
|
||||
break;
|
||||
case InternalLogLevel.WARN:
|
||||
this.Warn(format, arg);
|
||||
break;
|
||||
case InternalLogLevel.ERROR:
|
||||
this.Error(format, arg);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(InternalLogLevel level, string format, object argA, object argB)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case InternalLogLevel.TRACE:
|
||||
this.Trace(format, argA, argB);
|
||||
break;
|
||||
case InternalLogLevel.DEBUG:
|
||||
this.Debug(format, argA, argB);
|
||||
break;
|
||||
case InternalLogLevel.INFO:
|
||||
this.Info(format, argA, argB);
|
||||
break;
|
||||
case InternalLogLevel.WARN:
|
||||
this.Warn(format, argA, argB);
|
||||
break;
|
||||
case InternalLogLevel.ERROR:
|
||||
this.Error(format, argA, argB);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(InternalLogLevel level, string format, params object[] arguments)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case InternalLogLevel.TRACE:
|
||||
this.Trace(format, arguments);
|
||||
break;
|
||||
case InternalLogLevel.DEBUG:
|
||||
this.Debug(format, arguments);
|
||||
break;
|
||||
case InternalLogLevel.INFO:
|
||||
this.Info(format, arguments);
|
||||
break;
|
||||
case InternalLogLevel.WARN:
|
||||
this.Warn(format, arguments);
|
||||
break;
|
||||
case InternalLogLevel.ERROR:
|
||||
this.Error(format, arguments);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.GetType().Name + '(' + this.Name + ')'; // todo: port: revert: StringUtil.simpleClassName(this) + '(' + name() + ')';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
|
||||
[EventSource(Name = "DotNetty-Default")]
|
||||
public class DefaultEventSource : EventSource
|
||||
{
|
||||
const int TraceEventId = 1;
|
||||
const int DebugEventId = 2;
|
||||
const int InfoEventId = 3;
|
||||
const int WarningEventId = 4;
|
||||
const int ErrorEventId = 5;
|
||||
|
||||
public class Keywords
|
||||
{
|
||||
public const EventKeywords TraceEventKeyword = (EventKeywords)(1);
|
||||
public const EventKeywords DebugEventKeyword = (EventKeywords)(1 << 1);
|
||||
}
|
||||
|
||||
public static readonly DefaultEventSource Log = new DefaultEventSource();
|
||||
|
||||
DefaultEventSource()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsTraceEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Verbose, Keywords.TraceEventKeyword); }
|
||||
}
|
||||
|
||||
public bool IsDebugEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Verbose, Keywords.DebugEventKeyword); }
|
||||
}
|
||||
|
||||
public bool IsInfoEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Informational, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsWarningEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Warning, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsErrorEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Error, EventKeywords.None); }
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Trace(string source, string message)
|
||||
{
|
||||
this.Trace(source, message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Trace(string source, string message, Exception exception)
|
||||
{
|
||||
if (this.IsTraceEnabled)
|
||||
{
|
||||
this.Trace(source, message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(TraceEventId, Level = EventLevel.Verbose, Keywords = Keywords.TraceEventKeyword)]
|
||||
public void Trace(string source, string message, string info)
|
||||
{
|
||||
if (this.IsTraceEnabled)
|
||||
{
|
||||
this.WriteEvent(TraceEventId, source, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Debug(string source, string message)
|
||||
{
|
||||
this.Debug(source, message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Debug(string source, string message, Exception exception)
|
||||
{
|
||||
if (this.IsDebugEnabled)
|
||||
{
|
||||
this.Debug(source, message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(DebugEventId, Level = EventLevel.Verbose, Keywords = Keywords.DebugEventKeyword)]
|
||||
public void Debug(string source, string message, string info)
|
||||
{
|
||||
if (this.IsDebugEnabled)
|
||||
{
|
||||
this.WriteEvent(DebugEventId, source, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Info(string source, string message)
|
||||
{
|
||||
this.Info(source, message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Info(string source, string message, Exception exception)
|
||||
{
|
||||
if (this.IsInfoEnabled)
|
||||
{
|
||||
this.Info(source, message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(InfoEventId, Level = EventLevel.Informational)]
|
||||
public void Info(string source, string message, string info)
|
||||
{
|
||||
if (this.IsInfoEnabled)
|
||||
{
|
||||
this.WriteEvent(InfoEventId, source, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string source, string message)
|
||||
{
|
||||
this.Warning(source, message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string source, string message, Exception exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.Warning(source, message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(WarningEventId, Level = EventLevel.Warning)]
|
||||
public void Warning(string source, string message, string exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.WriteEvent(WarningEventId, source, message, exception);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Error(string source, string message)
|
||||
{
|
||||
this.Error(source, message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Error(string source, string message, Exception exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.Error(source, message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(ErrorEventId, Level = EventLevel.Error)]
|
||||
public void Error(string source, string message, string exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.WriteEvent(ErrorEventId, source, message, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,445 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
using System;
|
||||
|
||||
sealed class EventSourceLogger : AbstractInternalLogger
|
||||
{
|
||||
public EventSourceLogger(string name)
|
||||
: base(name)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the TRACE level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level TRACE, false otherwise.</value>
|
||||
public override bool TraceEnabled
|
||||
{
|
||||
get { return DefaultEventSource.Log.IsTraceEnabled; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level TRACE.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
public override void Trace(string msg)
|
||||
{
|
||||
DefaultEventSource.Log.Trace(this.Name, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level TRACE according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level TRACE.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
public override void Trace(string format, object arg)
|
||||
{
|
||||
if (this.TraceEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, arg);
|
||||
DefaultEventSource.Log.Trace(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level TRACE according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level TRACE.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
public override void Trace(string format, object argA, object argB)
|
||||
{
|
||||
if (this.TraceEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, argA, argB);
|
||||
DefaultEventSource.Log.Trace(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level TRACE according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level TRACE.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
public override void Trace(string format, params object[] arguments)
|
||||
{
|
||||
if (this.TraceEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments);
|
||||
DefaultEventSource.Log.Trace(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level TRACE with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
public override void Trace(string msg, Exception t)
|
||||
{
|
||||
DefaultEventSource.Log.Trace(this.Name, msg, t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the DEBUG level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level DEBUG, false otherwise.</value>
|
||||
public override bool DebugEnabled
|
||||
{
|
||||
get { return DefaultEventSource.Log.IsDebugEnabled; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level DEBUG.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
public override void Debug(string msg)
|
||||
{
|
||||
DefaultEventSource.Log.Debug(this.Name, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level DEBUG according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level DEBUG.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
public override void Debug(string format, object arg)
|
||||
{
|
||||
if (this.DebugEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, arg);
|
||||
DefaultEventSource.Log.Debug(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level DEBUG according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level DEBUG.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
public override void Debug(string format, object argA, object argB)
|
||||
{
|
||||
if (this.DebugEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, argA, argB);
|
||||
DefaultEventSource.Log.Debug(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level DEBUG according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level DEBUG.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
public override void Debug(string format, params object[] arguments)
|
||||
{
|
||||
if (this.DebugEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments);
|
||||
DefaultEventSource.Log.Debug(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level DEBUG with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
public override void Debug(string msg, Exception t)
|
||||
{
|
||||
DefaultEventSource.Log.Debug(this.Name, msg, t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the INFO level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level INFO, false otherwise.</value>
|
||||
public override bool InfoEnabled
|
||||
{
|
||||
get { return DefaultEventSource.Log.IsInfoEnabled; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level INFO.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
public override void Info(string msg)
|
||||
{
|
||||
DefaultEventSource.Log.Info(this.Name, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level INFO according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level INFO.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
public override void Info(string format, object arg)
|
||||
{
|
||||
if (this.InfoEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, arg);
|
||||
DefaultEventSource.Log.Info(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level INFO according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level INFO.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
public override void Info(string format, object argA, object argB)
|
||||
{
|
||||
if (this.InfoEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, argA, argB);
|
||||
DefaultEventSource.Log.Info(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level INFO according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level INFO.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
public override void Info(string format, params object[] arguments)
|
||||
{
|
||||
if (this.InfoEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments);
|
||||
DefaultEventSource.Log.Info(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level INFO with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
public override void Info(string msg, Exception t)
|
||||
{
|
||||
DefaultEventSource.Log.Info(this.Name, msg, t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the WARN level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level WARN, false otherwise.</value>
|
||||
public override bool WarnEnabled
|
||||
{
|
||||
get { return DefaultEventSource.Log.IsWarningEnabled; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level WARN.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
public override void Warn(string msg)
|
||||
{
|
||||
DefaultEventSource.Log.Warning(this.Name, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level WARN according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level WARN.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
public override void Warn(string format, object arg)
|
||||
{
|
||||
if (this.WarnEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, arg);
|
||||
DefaultEventSource.Log.Warning(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level WARN according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level WARN.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
public override void Warn(string format, object argA, object argB)
|
||||
{
|
||||
if (this.WarnEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, argA, argB);
|
||||
DefaultEventSource.Log.Warning(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level WARN according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level WARN.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
public override void Warn(string format, params object[] arguments)
|
||||
{
|
||||
if (this.WarnEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments);
|
||||
DefaultEventSource.Log.Warning(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level WARN with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
public override void Warn(string msg, Exception t)
|
||||
{
|
||||
DefaultEventSource.Log.Warning(this.Name, msg, t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the ERROR level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level ERROR, false otherwise.</value>
|
||||
public override bool ErrorEnabled
|
||||
{
|
||||
get { return DefaultEventSource.Log.IsErrorEnabled; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level ERROR.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
public override void Error(string msg)
|
||||
{
|
||||
DefaultEventSource.Log.Error(this.Name, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level ERROR according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level ERROR.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
public override void Error(string format, object arg)
|
||||
{
|
||||
if (this.ErrorEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, arg);
|
||||
DefaultEventSource.Log.Error(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level ERROR according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level ERROR.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
public override void Error(string format, object argA, object argB)
|
||||
{
|
||||
if (this.ErrorEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.Format(format, argA, argB);
|
||||
DefaultEventSource.Log.Error(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level ERROR according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level ERROR.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
public override void Error(string format, params object[] arguments)
|
||||
{
|
||||
if (this.ErrorEnabled)
|
||||
{
|
||||
FormattingTuple ft = MessageFormatter.ArrayFormat(format, arguments);
|
||||
DefaultEventSource.Log.Error(this.Name, ft.Message, ft.Exception);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level ERROR with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
public override void Error(string msg, Exception t)
|
||||
{
|
||||
DefaultEventSource.Log.Error(this.Name, msg, t);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
class EventSourceLoggerFactory : InternalLoggerFactory
|
||||
{
|
||||
protected internal override IInternalLogger NewInstance(string name)
|
||||
{
|
||||
return new EventSourceLogger(name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the results of formatting done by {@link MessageFormatter}.
|
||||
/// </summary>
|
||||
class FormattingTuple
|
||||
{
|
||||
static readonly FormattingTuple NULL = new FormattingTuple(null);
|
||||
|
||||
public FormattingTuple(string message)
|
||||
: this(message, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public FormattingTuple(string message, object[] argArray, Exception exception)
|
||||
{
|
||||
this.Message = message;
|
||||
this.Exception = exception;
|
||||
if (exception == null)
|
||||
{
|
||||
this.ArgArray = argArray;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ArgArray = GetTrimmedCopy(argArray);
|
||||
}
|
||||
}
|
||||
|
||||
static object[] GetTrimmedCopy(object[] argArray)
|
||||
{
|
||||
Contract.Requires(argArray != null && argArray.Length > 0);
|
||||
|
||||
int trimemdLen = argArray.Length - 1;
|
||||
var trimmed = new object[trimemdLen];
|
||||
Array.Copy(argArray, 0, trimmed, 0, trimemdLen);
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
public string Message { get; private set; }
|
||||
|
||||
public object[] ArgArray { get; private set; }
|
||||
|
||||
public Exception Exception { get; private set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,430 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// <em>Internal-use-only</em> logger used by DotNetty. <strong>DO NOT</strong>
|
||||
/// access this class outside of DotNetty.
|
||||
/// </summary>
|
||||
public interface IInternalLogger
|
||||
{
|
||||
/// <summary>
|
||||
/// Return the name of this <see cref="IInternalLogger" /> instance.
|
||||
/// </summary>
|
||||
/// <value>name of this logger instance</value>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the TRACE level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level TRACE, false otherwise.</value>
|
||||
bool TraceEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level TRACE.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
void Trace(string msg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level TRACE according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level TRACE.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
void Trace(string format, object arg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level TRACE according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level TRACE.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
void Trace(string format, object argA, object argB);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level TRACE according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level TRACE. However, this variant incurs the hidden
|
||||
/// (and relatively small) cost of creating an <c>object[]</c>
|
||||
/// before invoking the method,
|
||||
/// even if this logger is disabled for TRACE. The variants
|
||||
/// <see cref="Trace(string, object)" /> and <see cref="Trace(string, object, object)" />
|
||||
/// arguments exist solely to avoid this hidden cost.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
void Trace(string format, params object[] arguments);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level TRACE with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Trace(string msg, Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level TRACE.
|
||||
/// </summary>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Trace(Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the DEBUG level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level DEBUG, false otherwise.</value>
|
||||
bool DebugEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level DEBUG.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
void Debug(string msg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level DEBUG according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level DEBUG.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
void Debug(string format, object arg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level DEBUG according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level DEBUG.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
void Debug(string format, object argA, object argB);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level DEBUG according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level DEBUG. However, this variant incurs the hidden
|
||||
/// (and relatively small) cost of creating an <c>object[]</c>
|
||||
/// before invoking the method,
|
||||
/// even if this logger is disabled for DEBUG. The variants
|
||||
/// <see cref="Debug(string, object)" /> and <see cref="Debug(string, object, object)" />
|
||||
/// arguments exist solely to avoid this hidden cost.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
void Debug(string format, params object[] arguments);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level DEBUG with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Debug(string msg, Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level DEBUG.
|
||||
/// </summary>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Debug(Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the INFO level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level INFO, false otherwise.</value>
|
||||
bool InfoEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level INFO.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
void Info(string msg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level INFO according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level INFO.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
void Info(string format, object arg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level INFO according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level INFO.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
void Info(string format, object argA, object argB);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level INFO according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level INFO. However, this variant incurs the hidden
|
||||
/// (and relatively small) cost of creating an <c>object[]</c>
|
||||
/// before invoking the method,
|
||||
/// even if this logger is disabled for INFO. The variants
|
||||
/// <see cref="Info(string, object)" /> and <see cref="Info(string, object, object)" />
|
||||
/// arguments exist solely to avoid this hidden cost.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
void Info(string format, params object[] arguments);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level INFO with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Info(string msg, Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level INFO.
|
||||
/// </summary>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Info(Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the WARN level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level WARN, false otherwise.</value>
|
||||
bool WarnEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level WARN.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
void Warn(string msg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level WARN according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level WARN.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
void Warn(string format, object arg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level WARN according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level WARN. However, this variant incurs the hidden
|
||||
/// (and relatively small) cost of creating an <c>object[]</c>
|
||||
/// before invoking the method,
|
||||
/// even if this logger is disabled for WARN. The variants
|
||||
/// <see cref="Warn(string, object)" /> and <see cref="Warn(string, object, object)" />
|
||||
/// arguments exist solely to avoid this hidden cost.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
void Warn(string format, params object[] arguments);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level WARN according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level WARN.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
void Warn(string format, object argA, object argB);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level WARN with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Warn(string msg, Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level WARN.
|
||||
/// </summary>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Warn(Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Is this logger instance enabled for the ERROR level?
|
||||
/// </summary>
|
||||
/// <value>true if this Logger is enabled for level ERROR, false otherwise.</value>
|
||||
bool ErrorEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at level ERROR.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
void Error(string msg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level ERROR according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level ERROR.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
void Error(string format, object arg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level ERROR according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level ERROR.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
void Error(string format, object argA, object argB);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at level ERROR according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for level ERROR. However, this variant incurs the hidden
|
||||
/// (and relatively small) cost of creating an <c>object[]</c>
|
||||
/// before invoking the method,
|
||||
/// even if this logger is disabled for ERROR. The variants
|
||||
/// <see cref="Error(string, object)" /> and <see cref="Error(string, object, object)" />
|
||||
/// arguments exist solely to avoid this hidden cost.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
void Error(string format, params object[] arguments);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level ERROR with an accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Error(string msg, Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at level ERROR.
|
||||
/// </summary>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Error(Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Is the logger instance enabled for the specified {@code level}?
|
||||
/// </summary>
|
||||
/// <param name="level">log level</param>
|
||||
/// <returns>true if this Logger is enabled for the specified {@code level}, false otherwise.</returns>
|
||||
bool IsEnabled(InternalLogLevel level);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message object at a specified <see cref="level" />.
|
||||
/// </summary>
|
||||
/// <param name="level">log level</param>
|
||||
/// <param name="msg">the message object to be logged</param>
|
||||
void Log(InternalLogLevel level, string msg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at a specified <see cref="level" /> according to the specified format and
|
||||
/// argument.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for the specified <see cref="level" />.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="level">log level</param>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arg">the argument</param>
|
||||
void Log(InternalLogLevel level, string format, object arg);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at a specified <see cref="level" /> according to the specified format and
|
||||
/// arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous object creation when the logger is disabled
|
||||
/// for the specified <see cref="level" />.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="level">log level</param>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="argA">the first argument</param>
|
||||
/// <param name="argB">the second argument</param>
|
||||
void Log(InternalLogLevel level, string format, object argA, object argB);
|
||||
|
||||
/// <summary>
|
||||
/// Log a message at the specified {@code level} according to the specified format
|
||||
/// and arguments.
|
||||
/// <p>
|
||||
/// This form avoids superfluous string concatenation when the logger
|
||||
/// is disabled for the specified {@code level}. However, this variant incurs the hidden
|
||||
/// (and relatively small) cost of creating an {@code Object[]} before invoking the method,
|
||||
/// even if this logger is disabled for the specified {@code level}. The variants
|
||||
/// <see cref="Log(InternalLogLevel, string, object)" /> and
|
||||
/// <see cref="Log(InternalLogLevel, string, object, object)" /> arguments exist solely
|
||||
/// in order to avoid this hidden cost.
|
||||
/// </p>
|
||||
/// </summary>
|
||||
/// <param name="level">log level</param>
|
||||
/// <param name="format">the format string</param>
|
||||
/// <param name="arguments">an array of arguments</param>
|
||||
void Log(InternalLogLevel level, string format, params object[] arguments);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at the specified <see cref="level" /> with an
|
||||
/// accompanying message.
|
||||
/// </summary>
|
||||
/// <param name="level">log level</param>
|
||||
/// <param name="msg">the message accompanying the exception</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Log(InternalLogLevel level, string msg, Exception t);
|
||||
|
||||
/// <summary>
|
||||
/// Log an exception at the specified <see cref="level" />.
|
||||
/// </summary>
|
||||
/// <param name="level">log level</param>
|
||||
/// <param name="t">the exception to log</param>
|
||||
void Log(InternalLogLevel level, Exception t);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
/// <summary>The log level that {@link IInternalLogger} can log at.</summary>
|
||||
public enum InternalLogLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// 'TRACE' log level.
|
||||
/// </summary>
|
||||
TRACE,
|
||||
|
||||
/// <summary>
|
||||
/// 'DEBUG' log level.
|
||||
/// </summary>
|
||||
DEBUG,
|
||||
|
||||
/// <summary>
|
||||
/// 'INFO' log level.
|
||||
/// </summary>
|
||||
INFO,
|
||||
|
||||
/// <summary>
|
||||
/// 'WARN' log level.
|
||||
/// </summary>
|
||||
WARN,
|
||||
|
||||
/// <summary>
|
||||
/// 'ERROR' log level.
|
||||
/// </summary>
|
||||
ERROR
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
using System.Diagnostics.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// Creates an <see cref="IInternalLogger"/> or changes the default factory
|
||||
/// implementation. This factory allows you to choose what logging framework
|
||||
/// Netty should use. The default factory is <see cref="EventSourceLoggerFactory"/>
|
||||
/// You can change it to your preferred logging framework before other Netty classes are loaded:
|
||||
/// <pre>
|
||||
/// <code>InternalLoggerFactory.SetDefaultFactory(new MyLoggerFactory());</code>
|
||||
/// </pre>
|
||||
/// Please note that the new default factory is effective only for the classes
|
||||
/// which were loaded after the default factory is changed. Therefore,
|
||||
/// {@link #SetDefaultFactory(InternalLoggerFactory)} should be called as early
|
||||
/// as possible and shouldn't be called more than once.
|
||||
/// </summary>
|
||||
public abstract class InternalLoggerFactory
|
||||
{
|
||||
static volatile InternalLoggerFactory defaultFactory =
|
||||
NewDefaultFactory(typeof(InternalLoggerFactory).FullName);
|
||||
|
||||
static InternalLoggerFactory()
|
||||
{
|
||||
// todo: port: revisit
|
||||
// Initiate some time-consuming background jobs here,
|
||||
// because this class is often initialized at the earliest time.
|
||||
//try {
|
||||
// Class.forName(ThreadLocalRandom.class.getName(), true, InternalLoggerFactory.class.getClassLoader());
|
||||
//} catch (Exception ignored) {
|
||||
// // Should not fail, but it does not harm to fail.
|
||||
//}
|
||||
}
|
||||
|
||||
static InternalLoggerFactory NewDefaultFactory(string name)
|
||||
{
|
||||
InternalLoggerFactory f = new EventSourceLoggerFactory();
|
||||
f.NewInstance(name).Debug("Using EventSource as the default logging framework");
|
||||
return f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default factory. The initial default factory is <see cref="EventSourceLoggerFactory"/>
|
||||
/// </summary>
|
||||
public static InternalLoggerFactory DefaultFactory
|
||||
{
|
||||
get { return defaultFactory; }
|
||||
set
|
||||
{
|
||||
Contract.Requires(value != null);
|
||||
|
||||
defaultFactory = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new logger instance with the name of the specified class.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static IInternalLogger GetInstance<T>()
|
||||
{
|
||||
return GetInstance(typeof(T).FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new logger instance with the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">logger name</param>
|
||||
/// <returns>logger instance</returns>
|
||||
public static IInternalLogger GetInstance(string name)
|
||||
{
|
||||
return DefaultFactory.NewInstance(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new logger instance with the specified name.
|
||||
/// </summary>
|
||||
/// <param name="name">logger name</param>
|
||||
/// <returns>logger instance</returns>
|
||||
protected internal abstract IInternalLogger NewInstance(string name);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,461 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Internal.Logging
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
/// <summary>
|
||||
/// Formats messages according to very simple substitution rules. Substitutions
|
||||
/// can be made 1, 2 or more arguments.
|
||||
/// <p />
|
||||
/// <p />
|
||||
/// For example,
|
||||
/// <p />
|
||||
/// <pre>
|
||||
/// MessageFormatter.Format("Hi {}.", "there")
|
||||
/// </pre>
|
||||
/// <p />
|
||||
/// will return the string "Hi there.".
|
||||
/// <p />
|
||||
/// The {} pair is called the <em>formatting anchor</em>. It serves to designate
|
||||
/// the location where arguments need to be substituted within the message
|
||||
/// pattern.
|
||||
/// <p />
|
||||
/// In case your message contains the '{' or the '}' character, you do not have
|
||||
/// to do anything special unless the '}' character immediately follows '{'. For
|
||||
/// example,
|
||||
/// <p />
|
||||
/// <pre>
|
||||
/// MessageFormatter.Format("Set {1,2,3} is not equal to {}.", "1,2");
|
||||
/// </pre>
|
||||
/// <p />
|
||||
/// will return the string "Set {1,2,3} is not equal to 1,2.".
|
||||
/// <p />
|
||||
/// <p />
|
||||
/// If for whatever reason you need to place the string "{}" in the message
|
||||
/// without its <em>formatting anchor</em> meaning, then you need to escape the
|
||||
/// '{' character with '\', that is the backslash character. Only the '{'
|
||||
/// character should be escaped. There is no need to escape the '}' character.
|
||||
/// For example,
|
||||
/// <p />
|
||||
/// <pre>
|
||||
/// MessageFormatter.Format("Set \\{} is not equal to {}.", "1,2");
|
||||
/// </pre>
|
||||
/// <p />
|
||||
/// will return the string "Set {} is not equal to 1,2.".
|
||||
/// <p />
|
||||
/// <p />
|
||||
/// The escaping behavior just described can be overridden by escaping the escape
|
||||
/// character '\'. Calling
|
||||
/// <p />
|
||||
/// <pre>
|
||||
/// MessageFormatter.Format("File name is C:\\\\{}.", "file.zip");
|
||||
/// </pre>
|
||||
/// <p />
|
||||
/// will return the string "File name is C:\file.zip".
|
||||
/// <p />
|
||||
/// <p />
|
||||
/// The formatting conventions are different than those of {@link MessageFormat}
|
||||
/// which ships with the Java platform. This is justified by the fact that
|
||||
/// SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.
|
||||
/// This local performance difference is both measurable and significant in the
|
||||
/// larger context of the complete logging processing chain.
|
||||
/// <p />
|
||||
/// <p />
|
||||
/// <seealso cref="Format(string, object)" />
|
||||
/// <seealso cref="Format(string, object, object)" />
|
||||
/// <seealso cref="ArrayFormat(string, object[])" />
|
||||
/// </summary>
|
||||
static class MessageFormatter
|
||||
{
|
||||
static readonly char DELIM_START = '{';
|
||||
static readonly string DELIM_STR = "{}";
|
||||
static readonly char ESCAPE_CHAR = '\\';
|
||||
|
||||
/// <summary>
|
||||
/// Performs single argument substitution for the 'messagePattern' passed as
|
||||
/// parameter.
|
||||
/// <p />
|
||||
/// For example,
|
||||
/// <p />
|
||||
/// <pre>
|
||||
/// MessageFormatter.Format("Hi {}.", "there");
|
||||
/// </pre>
|
||||
/// <p />
|
||||
/// will return the string "Hi there.".
|
||||
/// <p />
|
||||
/// </summary>
|
||||
/// <param name="messagePattern">The message pattern which will be parsed and formatted</param>
|
||||
/// <param name="arg">The argument to be substituted in place of the formatting anchor</param>
|
||||
/// <returns>The formatted message</returns>
|
||||
public static FormattingTuple Format(string messagePattern, object arg)
|
||||
{
|
||||
return ArrayFormat(messagePattern, new[] { arg });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a two argument substitution for the 'messagePattern' passed as
|
||||
/// parameter.
|
||||
/// <p/>
|
||||
/// For example,
|
||||
/// <p/>
|
||||
/// <pre>
|
||||
/// MessageFormatter.Format("Hi {}. My name is {}.", "Alice", "Bob");
|
||||
/// </pre>
|
||||
/// <p/>
|
||||
/// will return the string "Hi Alice. My name is Bob.".
|
||||
/// </summary>
|
||||
/// <param name="messagePattern">The message pattern which will be parsed and formatted</param>
|
||||
/// <param name="argA">The argument to be substituted in place of the first formatting anchor</param>
|
||||
/// <param name="argB">The argument to be substituted in place of the second formatting anchor</param>
|
||||
/// <returns>The formatted message</returns>
|
||||
public static FormattingTuple Format(string messagePattern,
|
||||
object argA, object argB)
|
||||
{
|
||||
return ArrayFormat(messagePattern, new object[] { argA, argB });
|
||||
}
|
||||
|
||||
public static Exception GetThrowableCandidate(object[] argArray)
|
||||
{
|
||||
if (argArray == null || argArray.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
object lastEntry = argArray[argArray.Length - 1];
|
||||
if (lastEntry is Exception)
|
||||
{
|
||||
return (Exception)lastEntry;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Same principle as the {@link #Format(String, Object)} and
|
||||
/// {@link #Format(String, Object, Object)} methods except that any number of
|
||||
/// arguments can be passed in an array.
|
||||
/// </summary>
|
||||
/// <param name="messagePattern">The message pattern which will be parsed and formatted</param>
|
||||
/// <param name="argArray">An array of arguments to be substituted in place of formatting anchors</param>
|
||||
/// <returns>The formatted message</returns>
|
||||
public static FormattingTuple ArrayFormat(string messagePattern,
|
||||
object[] argArray)
|
||||
{
|
||||
Exception throwableCandidate = GetThrowableCandidate(argArray);
|
||||
|
||||
if (messagePattern == null)
|
||||
{
|
||||
return new FormattingTuple(null, argArray, throwableCandidate);
|
||||
}
|
||||
|
||||
if (argArray == null)
|
||||
{
|
||||
return new FormattingTuple(messagePattern);
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
int j;
|
||||
var sbuf = new StringBuilder(messagePattern.Length + 50);
|
||||
|
||||
int l;
|
||||
for (l = 0; l < argArray.Length; l++)
|
||||
{
|
||||
j = messagePattern.IndexOf(DELIM_STR, i, StringComparison.Ordinal);
|
||||
|
||||
if (j == -1)
|
||||
{
|
||||
// no more variables
|
||||
if (i == 0)
|
||||
{
|
||||
// this is a simple string
|
||||
return new FormattingTuple(messagePattern, argArray,
|
||||
throwableCandidate);
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the tail string which contains no variables and return
|
||||
// the result.
|
||||
sbuf.Append(messagePattern.Substring(i, messagePattern.Length - i));
|
||||
return new FormattingTuple(sbuf.ToString(), argArray,
|
||||
throwableCandidate);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsEscapedDelimeter(messagePattern, j))
|
||||
{
|
||||
if (!IsDoubleEscaped(messagePattern, j))
|
||||
{
|
||||
l--; // DELIM_START was escaped, thus should not be incremented
|
||||
sbuf.Append(messagePattern.Substring(i, j - 1 - i));
|
||||
sbuf.Append(DELIM_START);
|
||||
i = j + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The escape character preceding the delimiter start is
|
||||
// itself escaped: "abc x:\\{}"
|
||||
// we have to consume one backward slash
|
||||
sbuf.Append(messagePattern.Substring(i, j - 1 - i));
|
||||
DeeplyAppendParameter(sbuf, argArray[l], new HashSet<object[]>());
|
||||
i = j + 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal case
|
||||
sbuf.Append(messagePattern.Substring(i, j - i));
|
||||
DeeplyAppendParameter(sbuf, argArray[l], new HashSet<object[]>());
|
||||
i = j + 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
// append the characters following the last {} pair.
|
||||
sbuf.Append(messagePattern.Substring(i, messagePattern.Length - i));
|
||||
if (l < argArray.Length - 1)
|
||||
{
|
||||
return new FormattingTuple(sbuf.ToString(), argArray, throwableCandidate);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new FormattingTuple(sbuf.ToString(), argArray, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsEscapedDelimeter(string messagePattern,
|
||||
int delimeterStartIndex)
|
||||
{
|
||||
if (delimeterStartIndex == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return messagePattern[delimeterStartIndex - 1] == ESCAPE_CHAR;
|
||||
}
|
||||
|
||||
public static bool IsDoubleEscaped(string messagePattern,
|
||||
int delimeterStartIndex)
|
||||
{
|
||||
return delimeterStartIndex >= 2 && messagePattern[delimeterStartIndex - 2] == ESCAPE_CHAR;
|
||||
}
|
||||
|
||||
// special treatment of array values was suggested by 'lizongbo'
|
||||
static void DeeplyAppendParameter(StringBuilder sbuf, object o,
|
||||
ISet<object[]> seenMap)
|
||||
{
|
||||
if (o == null)
|
||||
{
|
||||
sbuf.Append("null");
|
||||
return;
|
||||
}
|
||||
if (!o.GetType().IsArray)
|
||||
{
|
||||
SafeObjectAppend(sbuf, o);
|
||||
}
|
||||
else
|
||||
{
|
||||
// check for primitive array types because they
|
||||
// unfortunately cannot be cast to Object[]
|
||||
if (o is bool[])
|
||||
{
|
||||
BooleanArrayAppend(sbuf, (bool[])o);
|
||||
}
|
||||
else if (o is byte[])
|
||||
{
|
||||
ByteArrayAppend(sbuf, (byte[])o);
|
||||
}
|
||||
else if (o is char[])
|
||||
{
|
||||
CharArrayAppend(sbuf, (char[])o);
|
||||
}
|
||||
else if (o is short[])
|
||||
{
|
||||
ShortArrayAppend(sbuf, (short[])o);
|
||||
}
|
||||
else if (o is int[])
|
||||
{
|
||||
IntArrayAppend(sbuf, (int[])o);
|
||||
}
|
||||
else if (o is long[])
|
||||
{
|
||||
LongArrayAppend(sbuf, (long[])o);
|
||||
}
|
||||
else if (o is float[])
|
||||
{
|
||||
FloatArrayAppend(sbuf, (float[])o);
|
||||
}
|
||||
else if (o is double[])
|
||||
{
|
||||
DoubleArrayAppend(sbuf, (double[])o);
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjectArrayAppend(sbuf, (object[])o, seenMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SafeObjectAppend(StringBuilder sbuf, object o)
|
||||
{
|
||||
try
|
||||
{
|
||||
string oAsString = o.ToString();
|
||||
sbuf.Append(oAsString);
|
||||
}
|
||||
catch (Exception t)
|
||||
{
|
||||
Console.Error.WriteLine("Failed ToString() invocation on an object of type ["
|
||||
+ o.GetType().Name + "]:" + Environment.NewLine + t);
|
||||
sbuf.Append("[FAILED toString()]");
|
||||
}
|
||||
}
|
||||
|
||||
static void ObjectArrayAppend(StringBuilder sbuf, object[] a,
|
||||
ISet<object[]> seenMap)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
if (!seenMap.Contains(a))
|
||||
{
|
||||
seenMap.Add(a);
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
DeeplyAppendParameter(sbuf, a[i], seenMap);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
// allow repeats in siblings
|
||||
seenMap.Remove(a);
|
||||
}
|
||||
else
|
||||
{
|
||||
sbuf.Append("...");
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
|
||||
static void BooleanArrayAppend(StringBuilder sbuf, bool[] a)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sbuf.Append(a[i]);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
|
||||
static void ByteArrayAppend(StringBuilder sbuf, byte[] a)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sbuf.Append(a[i]);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
|
||||
static void CharArrayAppend(StringBuilder sbuf, char[] a)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sbuf.Append(a[i]);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
|
||||
static void ShortArrayAppend(StringBuilder sbuf, short[] a)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sbuf.Append(a[i]);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
|
||||
static void IntArrayAppend(StringBuilder sbuf, int[] a)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sbuf.Append(a[i]);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
|
||||
static void LongArrayAppend(StringBuilder sbuf, long[] a)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sbuf.Append(a[i]);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
|
||||
static void FloatArrayAppend(StringBuilder sbuf, float[] a)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sbuf.Append(a[i]);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
|
||||
static void DoubleArrayAppend(StringBuilder sbuf, double[] a)
|
||||
{
|
||||
sbuf.Append('[');
|
||||
int len = a.Length;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
sbuf.Append(a[i]);
|
||||
if (i != len - 1)
|
||||
{
|
||||
sbuf.Append(", ");
|
||||
}
|
||||
}
|
||||
sbuf.Append(']');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly:InternalsVisibleTo("DotNetty.Common.Tests")]
|
|
@ -5,15 +5,14 @@ namespace DotNetty.Common
|
|||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Threading;
|
||||
|
||||
public class ThreadLocalPool
|
||||
{
|
||||
public class Handle
|
||||
public sealed class Handle
|
||||
{
|
||||
internal object Value;
|
||||
public object Value;
|
||||
internal readonly Stack Stack;
|
||||
|
||||
internal Handle(Stack stack)
|
||||
|
@ -42,7 +41,7 @@ namespace DotNetty.Common
|
|||
}
|
||||
}
|
||||
|
||||
internal class Stack : Stack<Handle>
|
||||
internal sealed class Stack : Stack<Handle>
|
||||
{
|
||||
public readonly ThreadLocalPool Owner;
|
||||
public readonly Thread Thread;
|
||||
|
@ -91,11 +90,7 @@ namespace DotNetty.Common
|
|||
|
||||
this.preCreate = preCreate;
|
||||
|
||||
#if TRACE
|
||||
this.threadLocal = new ThreadLocal<Stack>(this.InitializeStorage, true);
|
||||
#else
|
||||
this.threadLocal = new ThreadLocal<ThreadLocalPool.Stack>(this.InitializeStorage);
|
||||
#endif
|
||||
this.valueFactory = valueFactory;
|
||||
}
|
||||
|
||||
|
@ -112,18 +107,6 @@ namespace DotNetty.Common
|
|||
return stack;
|
||||
}
|
||||
|
||||
[Conditional("TRACE")]
|
||||
public void LogUsage(string context)
|
||||
{
|
||||
// todo: perf counter or log
|
||||
int bufferCountInStacks = 0;
|
||||
foreach (Stack x in this.threadLocal.Values)
|
||||
{
|
||||
bufferCountInStacks += x.Count;
|
||||
}
|
||||
Console.WriteLine(context + ": " + bufferCountInStacks);
|
||||
}
|
||||
|
||||
public T Take()
|
||||
{
|
||||
Stack stack = this.threadLocal.Value;
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
namespace DotNetty.Common.Utilities
|
||||
{
|
||||
using System;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
|
||||
public sealed class ReferenceCountUtil
|
||||
{
|
||||
//private static readonly InternalLogger logger = InternalLoggerFactory.getInstance(ReferenceCountUtil.class);
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<ReferenceCountUtil>();
|
||||
|
||||
/// <summary>
|
||||
/// Try to call {@link ReferenceCounted#retain()} if the specified message implements {@link ReferenceCounted}.
|
||||
|
@ -80,8 +81,7 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// todo: log
|
||||
//logger.warn("Failed to release a message: {}", msg, t);
|
||||
Logger.Warn("Failed to release a message: {}", msg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,10 +100,10 @@ namespace DotNetty.Common.Utilities
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// todo: log
|
||||
//if (logger.isWarnEnabled()) {
|
||||
// logger.warn("Failed to release a message: {} (decrement: {})", msg, decrement, t);
|
||||
//}
|
||||
if (Logger.WarnEnabled)
|
||||
{
|
||||
Logger.Warn("Failed to release a message: {} (decrement: {})", msg, decrement, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -374,14 +374,14 @@ namespace DotNetty.Handlers.Tls
|
|||
catch (Exception ex)
|
||||
{
|
||||
// todo: evaluate following:
|
||||
// only log in debug mode as it most likely harmless and latest chrome still trigger
|
||||
// only log in Debug mode as it most likely harmless and latest chrome still trigger
|
||||
// this all the time.
|
||||
//
|
||||
// See https://github.com/netty/netty/issues/1340
|
||||
//string msg = ex.Message;
|
||||
//if (msg == null || !msg.contains("possible truncation attack"))
|
||||
//{
|
||||
// logger.debug("{} SSLEngine.closeInbound() raised an exception.", ctx.channel(), e);
|
||||
// logger.Debug("{} SSLEngine.closeInbound() raised an exception.", ctx.channel(), e);
|
||||
//}
|
||||
}
|
||||
this.NotifyHandshakeFailure(cause);
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Transport.Channels;
|
||||
|
||||
/// <summary>
|
||||
|
@ -20,6 +21,8 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
/// </summary>
|
||||
public class Bootstrap : AbstractBootstrap<Bootstrap, IChannel>
|
||||
{
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<Bootstrap>();
|
||||
|
||||
static readonly INameResolver DefaultResolver = new DefaultNameResolver();
|
||||
|
||||
volatile INameResolver resolver = DefaultResolver;
|
||||
|
@ -194,12 +197,12 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
{
|
||||
if (!channel.Configuration.SetOption(e.Key, e.Value))
|
||||
{
|
||||
BootstrapEventSource.Log.Warning("Unknown channel option: " + e);
|
||||
Logger.Warn("Unknown channel option: " + e);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BootstrapEventSource.Log.Warning("Failed to set a channel option: " + channel, ex);
|
||||
Logger.Warn("Failed to set a channel option: " + channel, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Bootstrapping
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
|
||||
[EventSource(Name = "DotNetty-Bootstrap")]
|
||||
public class BootstrapEventSource : EventSource
|
||||
{
|
||||
const int VerboseEventId = 1;
|
||||
const int InfoEventId = 2;
|
||||
const int WarningEventId = 3;
|
||||
const int ErrorEventId = 4;
|
||||
|
||||
public static readonly BootstrapEventSource Log = new BootstrapEventSource();
|
||||
|
||||
BootstrapEventSource()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsVerboseEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Verbose, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsInfoEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Informational, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsWarningEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Warning, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsErrorEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Error, EventKeywords.None); }
|
||||
}
|
||||
|
||||
[Event(VerboseEventId, Level = EventLevel.Verbose)]
|
||||
public void Verbose(string message, string info)
|
||||
{
|
||||
if (this.IsVerboseEnabled)
|
||||
{
|
||||
this.WriteEvent(VerboseEventId, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[Event(InfoEventId, Level = EventLevel.Informational)]
|
||||
public void Info(string message, string info)
|
||||
{
|
||||
if (this.IsInfoEnabled)
|
||||
{
|
||||
this.WriteEvent(InfoEventId, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string message)
|
||||
{
|
||||
this.Warning(message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string message, Exception exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.Warning(message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(WarningEventId, Level = EventLevel.Warning)]
|
||||
public void Warning(string message, string exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.WriteEvent(WarningEventId, message, exception);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Error(string message, Exception exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.Error(message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(ErrorEventId, Level = EventLevel.Error)]
|
||||
public void Error(string message, string exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.WriteEvent(ErrorEventId, message, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Common.Utilities;
|
||||
using DotNetty.Transport.Channels;
|
||||
|
||||
|
@ -21,7 +22,7 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
/// </summary>
|
||||
public class ServerBootstrap : AbstractBootstrap<ServerBootstrap, IServerChannel>
|
||||
{
|
||||
//private static final InternalLogger logger = InternalLoggerFactory.getInstance(ServerBootstrap.class);
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<ServerBootstrap>();
|
||||
|
||||
readonly ConcurrentDictionary<ChannelOption, object> childOptions;
|
||||
// todo: attrs
|
||||
|
@ -138,12 +139,12 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
{
|
||||
if (!channel.Configuration.SetOption(e.Key, e.Value))
|
||||
{
|
||||
BootstrapEventSource.Log.Warning("Unknown channel option: " + e);
|
||||
Logger.Warn("Unknown channel option: " + e);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BootstrapEventSource.Log.Warning("Failed to set a channel option: " + channel, ex);
|
||||
Logger.Warn("Failed to set a channel option: " + channel, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +187,7 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
}
|
||||
if (this.childGroup == null)
|
||||
{
|
||||
BootstrapEventSource.Log.Warning("childGroup is not set. Using parentGroup instead.");
|
||||
Logger.Warn("childGroup is not set. Using parentGroup instead.");
|
||||
this.childGroup = this.Group();
|
||||
}
|
||||
return this;
|
||||
|
@ -263,7 +264,7 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
{
|
||||
if (!this.childOptionsSetupFunc(child.Configuration))
|
||||
{
|
||||
BootstrapEventSource.Log.Warning("Not all configuration options could be set.");
|
||||
Logger.Warn("Not all configuration options could be set.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,7 +288,7 @@ namespace DotNetty.Transport.Bootstrapping
|
|||
static void ForceClose(IChannel child, Exception ex)
|
||||
{
|
||||
child.Unsafe.CloseForcibly();
|
||||
BootstrapEventSource.Log.Warning("Failed to register an accepted channel: " + child, ex);
|
||||
Logger.Warn("Failed to register an accepted channel: " + child, ex);
|
||||
}
|
||||
|
||||
public override void ExceptionCaught(IChannelHandlerContext ctx, Exception cause)
|
||||
|
|
|
@ -11,11 +11,12 @@ namespace DotNetty.Transport.Channels
|
|||
using System.Threading.Tasks;
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Common.Utilities;
|
||||
|
||||
public abstract class AbstractChannel : /*DefaultAttributeMap, */ IChannel
|
||||
{
|
||||
//static readonly InternalLogger logger = InternalLoggerFactory.getInstance(AbstractChannel.class);
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<AbstractChannel>();
|
||||
|
||||
protected static readonly ClosedChannelException ClosedChannelException = new ClosedChannelException();
|
||||
static readonly NotYetConnectedException NotYetConnectedException = new NotYetConnectedException();
|
||||
|
@ -441,12 +442,12 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ChannelEventSource.Log.Warning(
|
||||
Logger.Warn(
|
||||
string.Format("Force-closing a channel whose registration task was not accepted by an event loop: {0}", this.channel),
|
||||
ex);
|
||||
this.CloseForcibly();
|
||||
this.channel.closeFuture.Complete();
|
||||
Util.SafeSetFailure(promise, ex);
|
||||
Util.SafeSetFailure(promise, ex, Logger);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,7 +462,7 @@ namespace DotNetty.Transport.Channels
|
|||
// call was outside of the eventLoop
|
||||
if (!promise.setUncancellable() || !this.EnsureOpen(promise))
|
||||
{
|
||||
Util.SafeSetFailure(promise, ClosedChannelException);
|
||||
Util.SafeSetFailure(promise, ClosedChannelException, Logger);
|
||||
return;
|
||||
}
|
||||
bool firstRegistration = this.neverRegistered;
|
||||
|
@ -469,7 +470,7 @@ namespace DotNetty.Transport.Channels
|
|||
this.neverRegistered = false;
|
||||
this.channel.registered = true;
|
||||
this.channel.eventLoop.AcceptNewTasks();
|
||||
Util.SafeSetSuccess(promise);
|
||||
Util.SafeSetSuccess(promise, Logger);
|
||||
this.channel.pipeline.FireChannelRegistered();
|
||||
// Only fire a channelActive if the channel has never been registered. This prevents firing
|
||||
// multiple channel actives if the channel is deregistered and re-registered.
|
||||
|
@ -483,7 +484,7 @@ namespace DotNetty.Transport.Channels
|
|||
// Close the channel directly to avoid FD leak.
|
||||
this.CloseForcibly();
|
||||
this.channel.closeFuture.Complete();
|
||||
Util.SafeSetFailure(promise, t);
|
||||
Util.SafeSetFailure(promise, t, Logger);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -503,7 +504,7 @@ namespace DotNetty.Transport.Channels
|
|||
//{
|
||||
// // Warn a user about the fact that a non-root user can't receive a
|
||||
// // broadcast packet on *nix if the socket is bound on non-wildcard address.
|
||||
// logger.warn(
|
||||
// logger.Warn(
|
||||
// "A non-root user can't receive a broadcast packet if the socket " +
|
||||
// "is not bound to a wildcard address; binding to a non-wildcard " +
|
||||
// "address (" + localAddress + ") anyway as requested.");
|
||||
|
@ -517,7 +518,7 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (Exception t)
|
||||
{
|
||||
Util.SafeSetFailure(promise, t);
|
||||
Util.SafeSetFailure(promise, t, Logger);
|
||||
this.CloseIfClosed();
|
||||
return promise.Task;
|
||||
}
|
||||
|
@ -536,7 +537,7 @@ namespace DotNetty.Transport.Channels
|
|||
|
||||
void SafeSetFailure(TaskCompletionSource promise, Exception cause)
|
||||
{
|
||||
Util.SafeSetFailure(promise, cause);
|
||||
Util.SafeSetFailure(promise, cause, Logger);
|
||||
}
|
||||
|
||||
public Task DisconnectAsync()
|
||||
|
@ -572,7 +573,7 @@ namespace DotNetty.Transport.Channels
|
|||
|
||||
void SafeSetSuccess(TaskCompletionSource promise)
|
||||
{
|
||||
Util.SafeSetSuccess(promise);
|
||||
Util.SafeSetSuccess(promise, Logger);
|
||||
}
|
||||
|
||||
public Task CloseAsync() //CancellationToken cancellationToken)
|
||||
|
@ -601,7 +602,7 @@ namespace DotNetty.Transport.Channels
|
|||
if (this.channel.closeFuture.Task.IsCompleted)
|
||||
{
|
||||
// Closed already.
|
||||
Util.SafeSetSuccess(promise);
|
||||
Util.SafeSetSuccess(promise, Logger);
|
||||
return promise.Task;
|
||||
}
|
||||
|
||||
|
@ -697,7 +698,7 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Failed to close a channel.", e);
|
||||
Logger.Warn("Failed to close a channel.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -726,7 +727,7 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (Exception t)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Unexpected exception occurred while deregistering a channel.", t);
|
||||
Logger.Warn("Unexpected exception occurred while deregistering a channel.", t);
|
||||
return TaskEx.FromException(t);
|
||||
}
|
||||
finally
|
||||
|
@ -872,7 +873,7 @@ namespace DotNetty.Transport.Channels
|
|||
return true;
|
||||
}
|
||||
|
||||
Util.SafeSetFailure(promise, ClosedChannelException);
|
||||
Util.SafeSetFailure(promise, ClosedChannelException, Logger);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -909,7 +910,7 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (RejectedExecutionException e)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Can't invoke task later as EventLoop rejected it", e);
|
||||
Logger.Warn("Can't invoke task later as EventLoop rejected it", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Transport.Channels
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics.Tracing;
|
||||
|
||||
[EventSource(Name = "DotNetty-Channel")]
|
||||
public class ChannelEventSource : EventSource
|
||||
{
|
||||
const int VerboseEventId = 1;
|
||||
const int InfoEventId = 2;
|
||||
const int WarningEventId = 3;
|
||||
const int ErrorEventId = 4;
|
||||
|
||||
public static readonly ChannelEventSource Log = new ChannelEventSource();
|
||||
|
||||
ChannelEventSource()
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsVerboseEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Verbose, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsInfoEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Informational, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsWarningEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Warning, EventKeywords.None); }
|
||||
}
|
||||
|
||||
public bool IsErrorEnabled
|
||||
{
|
||||
get { return this.IsEnabled(EventLevel.Error, EventKeywords.None); }
|
||||
}
|
||||
|
||||
[Event(VerboseEventId, Level = EventLevel.Verbose)]
|
||||
public void Verbose(string message, string info)
|
||||
{
|
||||
if (this.IsVerboseEnabled)
|
||||
{
|
||||
this.WriteEvent(VerboseEventId, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[Event(InfoEventId, Level = EventLevel.Informational)]
|
||||
public void Info(string message, string info)
|
||||
{
|
||||
if (this.IsInfoEnabled)
|
||||
{
|
||||
this.WriteEvent(InfoEventId, message, info);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string message)
|
||||
{
|
||||
this.Warning(message, string.Empty);
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Warning(string message, Exception exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.Warning(message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(WarningEventId, Level = EventLevel.Warning)]
|
||||
public void Warning(string message, string exception)
|
||||
{
|
||||
if (this.IsWarningEnabled)
|
||||
{
|
||||
this.WriteEvent(WarningEventId, message, exception);
|
||||
}
|
||||
}
|
||||
|
||||
[NonEvent]
|
||||
public void Error(string message, Exception exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.Error(message, exception == null ? string.Empty : exception.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
[Event(ErrorEventId, Level = EventLevel.Error)]
|
||||
public void Error(string message, string exception)
|
||||
{
|
||||
if (this.IsErrorEnabled)
|
||||
{
|
||||
this.WriteEvent(ErrorEventId, message, exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,10 +68,10 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ChannelEventSource.Log.IsWarningEnabled)
|
||||
if (DefaultChannelPipeline.Logger.WarnEnabled)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("An exception was thrown by a user handler's exceptionCaught() method:", ex);
|
||||
ChannelEventSource.Log.Warning(".. and the cause of the exceptionCaught() was:", cause);
|
||||
DefaultChannelPipeline.Logger.Warn("An exception was thrown by a user handler's exceptionCaught() method:", ex);
|
||||
DefaultChannelPipeline.Logger.Warn(".. and the cause of the exceptionCaught() was:", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -227,9 +227,9 @@ namespace DotNetty.Transport.Channels
|
|||
{
|
||||
if (InExceptionCaught(cause))
|
||||
{
|
||||
if (ChannelEventSource.Log.IsWarningEnabled)
|
||||
if (DefaultChannelPipeline.Logger.WarnEnabled)
|
||||
{
|
||||
ChannelEventSource.Log.Warning(
|
||||
DefaultChannelPipeline.Logger.Warn(
|
||||
"An exception was thrown by a user handler " +
|
||||
"while handling an exceptionCaught event", cause);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
namespace DotNetty.Transport.Channels
|
||||
{
|
||||
using System;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// A special {@link ChannelHandler} which offers an easy way to initialize a {@link Channel} once it was
|
||||
|
@ -33,7 +34,7 @@ namespace DotNetty.Transport.Channels
|
|||
public abstract class ChannelInitializer<T> : ChannelHandlerAdapter
|
||||
where T : IChannel
|
||||
{
|
||||
//private static final InternalLogger logger = InternalLoggerFactory.getInstance(ChannelInitializer.class);
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<ChannelInitializer<T>>();
|
||||
|
||||
/// <summary>
|
||||
/// This method will be called once the {@link Channel} was registered. After the method returns this instance
|
||||
|
@ -49,7 +50,7 @@ namespace DotNetty.Transport.Channels
|
|||
get { return true; }
|
||||
}
|
||||
|
||||
public override sealed void ChannelRegistered(IChannelHandlerContext context)
|
||||
public sealed override void ChannelRegistered(IChannelHandlerContext context)
|
||||
{
|
||||
IChannelPipeline pipeline = context.Channel.Pipeline;
|
||||
bool success = false;
|
||||
|
@ -62,7 +63,7 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Failed to initialize a channel. Closing: " + context.Channel, ex);
|
||||
Logger.Warn("Failed to initialize a channel. Closing: " + context.Channel, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -9,12 +9,15 @@ namespace DotNetty.Transport.Channels
|
|||
using DotNetty.Buffers;
|
||||
using DotNetty.Common;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Common.Utilities;
|
||||
|
||||
public sealed class ChannelOutboundBuffer
|
||||
{
|
||||
#pragma warning disable 420 // all volatile fields are used with referenced in Interlocked methods only
|
||||
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<ChannelOutboundBuffer>();
|
||||
|
||||
//static readonly ThreadLocal<IByteBuffer[]> NIO_BUFFERS = new ThreadLocal<IByteBuffer[]>(() => new IByteBuffer[1024]);
|
||||
|
||||
readonly IChannel channel;
|
||||
|
@ -231,7 +234,7 @@ namespace DotNetty.Transport.Channels
|
|||
{
|
||||
// only release message, notify and decrement if it was not canceled before.
|
||||
ReferenceCountUtil.SafeRelease(msg);
|
||||
Util.SafeSetSuccess(promise);
|
||||
Util.SafeSetSuccess(promise, Logger);
|
||||
this.DecrementPendingOutboundBytes(size, false, true);
|
||||
}
|
||||
|
||||
|
@ -270,10 +273,10 @@ namespace DotNetty.Transport.Channels
|
|||
// only release message, fail and decrement if it was not canceled before.
|
||||
ReferenceCountUtil.SafeRelease(msg);
|
||||
|
||||
Util.SafeSetFailure(promise, cause);
|
||||
Util.SafeSetFailure(promise, cause, Logger);
|
||||
if (promise != TaskCompletionSource.Void && !promise.TrySetException(cause))
|
||||
{
|
||||
ChannelEventSource.Log.Warning(string.Format("Failed to mark a promise as failure because it's done already: {0}", promise), cause);
|
||||
Logger.Warn(string.Format("Failed to mark a promise as failure because it's done already: {0}", promise), cause);
|
||||
}
|
||||
this.DecrementPendingOutboundBytes(size, false, notifyWritability);
|
||||
}
|
||||
|
@ -678,10 +681,10 @@ namespace DotNetty.Transport.Channels
|
|||
if (!e.Cancelled)
|
||||
{
|
||||
ReferenceCountUtil.SafeRelease(e.Message);
|
||||
Util.SafeSetFailure(e.Promise, cause);
|
||||
Util.SafeSetFailure(e.Promise, cause, Logger);
|
||||
if (e.Promise != TaskCompletionSource.Void && !e.Promise.TrySetException(cause))
|
||||
{
|
||||
ChannelEventSource.Log.Warning(string.Format("Failed to mark a promise as failure because it's done already: {0}", e.Promise), cause);
|
||||
Logger.Warn(string.Format("Failed to mark a promise as failure because it's done already: {0}", e.Promise), cause);
|
||||
}
|
||||
}
|
||||
e = e.RecycleAndGetNext();
|
||||
|
|
|
@ -115,10 +115,10 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (Exception t)
|
||||
{
|
||||
if (ChannelEventSource.Log.IsWarningEnabled)
|
||||
if (DefaultChannelPipeline.Logger.WarnEnabled)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Failed to submit an exceptionCaught() event.", t);
|
||||
ChannelEventSource.Log.Warning("The exceptionCaught() event that was failed to submit was:", cause);
|
||||
DefaultChannelPipeline.Logger.Warn("Failed to submit an exceptionCaught() event.", t);
|
||||
DefaultChannelPipeline.Logger.Warn("The exceptionCaught() event that was failed to submit was:", cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,10 +13,13 @@ namespace DotNetty.Transport.Channels
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Common.Utilities;
|
||||
|
||||
sealed class DefaultChannelPipeline : IChannelPipeline
|
||||
{
|
||||
internal static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<DefaultChannelPipeline>();
|
||||
|
||||
static readonly ConditionalWeakTable<Type, string>[] NameCaches = CreateNameCaches();
|
||||
|
||||
static ConditionalWeakTable<Type, string>[] CreateNameCaches()
|
||||
|
@ -476,9 +479,9 @@ namespace DotNetty.Transport.Channels
|
|||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
if (ChannelEventSource.Log.IsWarningEnabled)
|
||||
if (Logger.WarnEnabled)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Failed to remove a handler: " + ctx.Name, ex2);
|
||||
Logger.Warn("Failed to remove a handler: " + ctx.Name, ex2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -954,7 +957,7 @@ namespace DotNetty.Transport.Channels
|
|||
{
|
||||
try
|
||||
{
|
||||
ChannelEventSource.Log.Warning(
|
||||
Logger.Warn(
|
||||
"An ExceptionCaught() event was fired, and it reached at the tail of the pipeline. " +
|
||||
"It usually means that no handler in the pipeline could handle the exception.",
|
||||
exception);
|
||||
|
@ -975,7 +978,7 @@ namespace DotNetty.Transport.Channels
|
|||
{
|
||||
try
|
||||
{
|
||||
ChannelEventSource.Log.Verbose(
|
||||
Logger.Debug(
|
||||
"Discarded inbound message {} that reached at the tail of the pipeline. " +
|
||||
"Please check your pipeline configuration.", message.ToString());
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace DotNetty.Transport.Channels
|
|||
using System.Threading.Tasks;
|
||||
using DotNetty.Common;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Common.Utilities;
|
||||
|
||||
/**
|
||||
|
@ -19,7 +20,7 @@ namespace DotNetty.Transport.Channels
|
|||
|
||||
public sealed class PendingWriteQueue
|
||||
{
|
||||
//private static final InternalLogger logger = InternalLoggerFactory.getInstance(PendingWriteQueue.class);
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<PendingWriteQueue>();
|
||||
|
||||
readonly IChannelHandlerContext ctx;
|
||||
readonly ChannelOutboundBuffer buffer;
|
||||
|
@ -300,7 +301,7 @@ namespace DotNetty.Transport.Channels
|
|||
{
|
||||
if ( /*!(promise instanceof VoidChannelPromise) && */!promise.TrySetException(cause))
|
||||
{
|
||||
// todo: log logger.warn("Failed to mark a promise as failure because it's done already: {}", promise, cause);
|
||||
Logger.Warn("Failed to mark a promise as failure because it's done already: {}", promise, cause);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,13 @@ namespace DotNetty.Transport.Channels.Sockets
|
|||
using System.Threading.Tasks;
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Common.Utilities;
|
||||
|
||||
public abstract class AbstractSocketChannel : AbstractChannel
|
||||
{
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<AbstractSocketChannel>();
|
||||
|
||||
[Flags]
|
||||
protected enum StateFlags
|
||||
{
|
||||
|
@ -58,9 +61,9 @@ namespace DotNetty.Transport.Channels.Sockets
|
|||
}
|
||||
catch (SocketException ex2)
|
||||
{
|
||||
if (ChannelEventSource.Log.IsWarningEnabled)
|
||||
if (Logger.WarnEnabled)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Failed to close a partially initialized socket.", ex2);
|
||||
Logger.Warn("Failed to close a partially initialized socket.", ex2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace DotNetty.Transport.Channels.Sockets
|
|||
using System.Diagnostics.Contracts;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// A {@link io.netty.channel.socket.ServerSocketChannel} implementation which uses
|
||||
|
@ -14,6 +15,8 @@ namespace DotNetty.Transport.Channels.Sockets
|
|||
/// </summary>
|
||||
public class TcpServerSocketChannel : AbstractSocketChannel, IServerSocketChannel
|
||||
{
|
||||
static readonly IInternalLogger Logger = InternalLoggerFactory.GetInstance<TcpServerSocketChannel>();
|
||||
|
||||
static readonly Action<object, object> ReadCompletedSyncCallback = OnReadCompletedSync;
|
||||
|
||||
readonly IServerSocketChannelConfiguration config;
|
||||
|
@ -208,7 +211,7 @@ namespace DotNetty.Transport.Channels.Sockets
|
|||
var asSocketException = ex as SocketException;
|
||||
if (asSocketException == null || asSocketException.SocketErrorCode != SocketError.WouldBlock)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Failed to create a new channel from an accepted socket.", ex);
|
||||
Logger.Warn("Failed to create a new channel from an accepted socket.", ex);
|
||||
if (connectedSocket != null)
|
||||
{
|
||||
try
|
||||
|
@ -217,7 +220,7 @@ namespace DotNetty.Transport.Channels.Sockets
|
|||
}
|
||||
catch (Exception ex2)
|
||||
{
|
||||
ChannelEventSource.Log.Warning("Failed to close a socket.", ex2);
|
||||
Logger.Warn("Failed to close a socket.", ex2);
|
||||
}
|
||||
}
|
||||
exception = ex;
|
||||
|
|
|
@ -5,28 +5,29 @@ namespace DotNetty.Transport.Channels
|
|||
{
|
||||
using System;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
|
||||
static class Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Marks the specified {@code promise} as success. If the {@code promise} is done already, log a message.
|
||||
/// </summary>
|
||||
public static void SafeSetSuccess(TaskCompletionSource promise)
|
||||
public static void SafeSetSuccess(TaskCompletionSource promise, IInternalLogger logger)
|
||||
{
|
||||
if (promise != TaskCompletionSource.Void && !promise.TryComplete())
|
||||
{
|
||||
ChannelEventSource.Log.Warning(string.Format("Failed to mark a promise as success because it is done already: {0}", promise));
|
||||
logger.Warn(string.Format("Failed to mark a promise as success because it is done already: {0}", promise));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks the specified {@code promise} as failure. If the {@code promise} is done already, log a message.
|
||||
/// </summary>
|
||||
public static void SafeSetFailure(TaskCompletionSource promise, Exception cause)
|
||||
public static void SafeSetFailure(TaskCompletionSource promise, Exception cause, IInternalLogger logger)
|
||||
{
|
||||
if (promise != TaskCompletionSource.Void && !promise.TrySetException(cause))
|
||||
{
|
||||
ChannelEventSource.Log.Warning(string.Format("Failed to mark a promise as failure because it's done already: {0}", promise), cause);
|
||||
logger.Warn(string.Format("Failed to mark a promise as failure because it's done already: {0}", promise), cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
</Compile>
|
||||
<Compile Include="Bootstrapping\AbstractBootstrap.cs" />
|
||||
<Compile Include="Bootstrapping\Bootstrap.cs" />
|
||||
<Compile Include="Bootstrapping\BootstrapEventSource.cs" />
|
||||
<Compile Include="Bootstrapping\DefaultNameResolver.cs" />
|
||||
<Compile Include="Bootstrapping\INameResolver.cs" />
|
||||
<Compile Include="Bootstrapping\ServerBootstrap.cs" />
|
||||
|
@ -48,7 +47,6 @@
|
|||
<Compile Include="Channels\AbstractChannel.cs" />
|
||||
<Compile Include="Channels\AbstractChannelHandlerContext.cs" />
|
||||
<Compile Include="Channels\ActionChannelInitializer.cs" />
|
||||
<Compile Include="Channels\ChannelEventSource.cs" />
|
||||
<Compile Include="Channels\ChannelException.cs" />
|
||||
<Compile Include="Channels\ChannelHandlerAdapter.cs" />
|
||||
<Compile Include="Channels\ChannelHandlerInvokerUtil.cs" />
|
||||
|
|
|
@ -40,7 +40,19 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Moq, Version=4.2.1507.118, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Moq.4.2.1507.0118\lib\net40\Moq.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Reactive.Core, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Reactive.Interfaces, Version=2.2.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="xunit.abstractions">
|
||||
<HintPath>..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
|
@ -64,6 +76,7 @@
|
|||
</Choose>
|
||||
<ItemGroup>
|
||||
<Compile Include="Concurrency\EventExecutorTests.cs" />
|
||||
<Compile Include="Internal\Logging\InternalLoggerFactoryTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -73,7 +86,9 @@
|
|||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="packages.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Choose>
|
||||
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
|
||||
|
@ -101,9 +116,7 @@
|
|||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props'))" />
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Common.Tests.Internal.Logging
|
||||
{
|
||||
using System;
|
||||
using System.Reactive.Disposables;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
public class InternalLoggerFactoryTest
|
||||
{
|
||||
// todo: CodeContracts on CI
|
||||
//[Fact]
|
||||
//public void ShouldNotAllowNullDefaultFactory()
|
||||
//{
|
||||
// Assert.ThrowsAny<Exception>(() => InternalLoggerFactory.DefaultFactory = null);
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public void ShouldGetInstance()
|
||||
{
|
||||
IInternalLogger one = InternalLoggerFactory.GetInstance("helloWorld");
|
||||
IInternalLogger two = InternalLoggerFactory.GetInstance<string>();
|
||||
|
||||
Assert.NotNull(one);
|
||||
Assert.NotNull(two);
|
||||
Assert.NotSame(one, two);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestMockReturned()
|
||||
{
|
||||
Mock<IInternalLogger> mock;
|
||||
using (SetupMockLogger(out mock))
|
||||
{
|
||||
mock.SetupGet(x => x.TraceEnabled).Returns(true).Verifiable();
|
||||
|
||||
IInternalLogger logger = InternalLoggerFactory.GetInstance("mock");
|
||||
|
||||
Assert.Equal(logger, mock.Object);
|
||||
Assert.True(logger.TraceEnabled);
|
||||
mock.Verify(x => x.TraceEnabled, Times.Once);
|
||||
}
|
||||
}
|
||||
|
||||
static IDisposable SetupMockLogger(out Mock<IInternalLogger> loggerMock)
|
||||
{
|
||||
InternalLoggerFactory oldLoggerFactory = InternalLoggerFactory.DefaultFactory;
|
||||
var factoryMock = new Mock<InternalLoggerFactory>(MockBehavior.Strict);
|
||||
InternalLoggerFactory mockFactory = factoryMock.Object;
|
||||
loggerMock = new Mock<IInternalLogger>(MockBehavior.Strict);
|
||||
|
||||
factoryMock.Setup(x => x.NewInstance("mock")).Returns(loggerMock.Object);
|
||||
InternalLoggerFactory.DefaultFactory = mockFactory;
|
||||
return Disposable.Create(() => InternalLoggerFactory.DefaultFactory = oldLoggerFactory);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Moq" version="4.2.1507.0118" targetFramework="net45" />
|
||||
<package id="Rx-Core" version="2.2.5" targetFramework="net45" />
|
||||
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" />
|
||||
<package id="xunit" version="2.0.0" targetFramework="net45" />
|
||||
<package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />
|
||||
<package id="xunit.assert" version="2.0.0" targetFramework="net45" />
|
||||
|
|
|
@ -3,10 +3,7 @@
|
|||
|
||||
namespace DotNetty.Tests.End2End
|
||||
{
|
||||
using DotNetty.Codecs.Mqtt;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Utility;
|
||||
using Xunit;
|
||||
|
||||
|
@ -15,10 +12,7 @@ namespace DotNetty.Tests.End2End
|
|||
[Fact]
|
||||
public void VerifyEventSources()
|
||||
{
|
||||
EventSourceAnalyzer.InspectAll(ExecutorEventSource.Log);
|
||||
EventSourceAnalyzer.InspectAll(ChannelEventSource.Log);
|
||||
EventSourceAnalyzer.InspectAll(BootstrapEventSource.Log);
|
||||
EventSourceAnalyzer.InspectAll(MqttEventSource.Log);
|
||||
EventSourceAnalyzer.InspectAll(DefaultEventSource.Log);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -86,6 +86,7 @@
|
|||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TestScenarioStep.cs" />
|
||||
<Compile Include="TestScenarioRunner.cs" />
|
||||
<Compile Include="XUnitOutputSink.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\DotNetty.Buffers\DotNetty.Buffers.csproj">
|
||||
|
@ -148,9 +149,7 @@
|
|||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.core.2.0.0\build\portable-net45+win+wpa81+wp80+monotouch+monoandroid+Xamarin.iOS\xunit.core.props'))" />
|
||||
<Error Condition="!Exists('..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\xunit.runner.visualstudio.2.0.0\build\net20\xunit.runner.visualstudio.props'))" />
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace DotNetty.Tests.End2End
|
|||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
@ -14,22 +15,28 @@ namespace DotNetty.Tests.End2End
|
|||
using DotNetty.Codecs.Mqtt;
|
||||
using DotNetty.Codecs.Mqtt.Packets;
|
||||
using DotNetty.Common.Concurrency;
|
||||
using DotNetty.Common.Internal.Logging;
|
||||
using DotNetty.Handlers.Tls;
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
using Microsoft.Practices.EnterpriseLibrary.SemanticLogging;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
public class End2EndTests
|
||||
public class End2EndTests : IDisposable
|
||||
{
|
||||
readonly ITestOutputHelper output;
|
||||
static readonly TimeSpan ShutdownTimeout = TimeSpan.FromSeconds(10);
|
||||
readonly ObservableEventListener eventListener;
|
||||
const int Port = 8009;
|
||||
|
||||
public End2EndTests(ITestOutputHelper output)
|
||||
{
|
||||
this.output = output;
|
||||
this.eventListener = new ObservableEventListener();
|
||||
this.eventListener.LogToTestOutput(output);
|
||||
this.eventListener.EnableEvents(DefaultEventSource.Log, EventLevel.Verbose);
|
||||
}
|
||||
|
||||
const string ClientId = "scenarioClient1";
|
||||
|
@ -325,5 +332,10 @@ namespace DotNetty.Tests.End2End
|
|||
Assert.Equal(message, Encoding.UTF8.GetString(responseMessage.ToArray()));
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.eventListener.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
namespace DotNetty.Tests.End2End
|
||||
{
|
||||
using System;
|
||||
using Microsoft.Practices.EnterpriseLibrary.SemanticLogging;
|
||||
using Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Formatters;
|
||||
using Microsoft.Practices.EnterpriseLibrary.SemanticLogging.Utility;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
public class XUnitOutputSink : IObserver<EventEntry>
|
||||
{
|
||||
static readonly object LockObject = new object();
|
||||
readonly ITestOutputHelper output;
|
||||
readonly IEventTextFormatter formatter;
|
||||
|
||||
public XUnitOutputSink(ITestOutputHelper output, IEventTextFormatter formatter)
|
||||
{
|
||||
this.output = output;
|
||||
this.formatter = formatter;
|
||||
}
|
||||
|
||||
public void OnCompleted()
|
||||
{
|
||||
}
|
||||
|
||||
public void OnError(Exception error)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnNext(EventEntry value)
|
||||
{
|
||||
string formattedValue = value.TryFormatAsString(this.formatter);
|
||||
if (formattedValue == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.OnNext(formattedValue);
|
||||
}
|
||||
|
||||
void OnNext(string entry)
|
||||
{
|
||||
lock (LockObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.output.WriteLine(entry);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SemanticLoggingEventSource.Log.CustomSinkUnhandledFault(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class XUnitOutputLog
|
||||
{
|
||||
public static SinkSubscription<XUnitOutputSink> LogToTestOutput(this IObservable<EventEntry> eventStream, ITestOutputHelper output, IEventTextFormatter formatter = null)
|
||||
{
|
||||
formatter = formatter ?? new EventTextFormatter();
|
||||
var sink = new XUnitOutputSink(output, formatter);
|
||||
return new SinkSubscription<XUnitOutputSink>(eventStream.Subscribe(sink), sink);
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче