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:
mgortman 2015-10-26 02:42:55 -07:00
Родитель 39aa6547bc
Коммит 0722ade2a8
52 изменённых файлов: 2401 добавлений и 547 удалений

Просмотреть файл

@ -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">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Simple"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;CAN_CHANGE_TO_IMPLICIT&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_WHEN_INITIALIZER_HAS_TYPE&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;IMPLICIT_EXCEPT_PRIMITIVE_TYPES&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSUpdateFileHeader&gt;True&lt;/CSUpdateFileHeader&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;StyleCop.Documentation&gt;&lt;SA1600ElementsMustBeDocumented&gt;False&lt;/SA1600ElementsMustBeDocumented&gt;&lt;SA1604ElementDocumentationMustHaveSummary&gt;False&lt;/SA1604ElementDocumentationMustHaveSummary&gt;&lt;SA1609PropertyDocumentationMustHaveValueDocumented&gt;False&lt;/SA1609PropertyDocumentationMustHaveValueDocumented&gt;&lt;SA1611ElementParametersMustBeDocumented&gt;False&lt;/SA1611ElementParametersMustBeDocumented&gt;&lt;SA1615ElementReturnValueMustBeDocumented&gt;False&lt;/SA1615ElementReturnValueMustBeDocumented&gt;&lt;SA1617VoidReturnValueMustNotBeDocumented&gt;False&lt;/SA1617VoidReturnValueMustNotBeDocumented&gt;&lt;SA1618GenericTypeParametersMustBeDocumented&gt;False&lt;/SA1618GenericTypeParametersMustBeDocumented&gt;&lt;SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;False&lt;/SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;&lt;SA1628DocumentationTextMustBeginWithACapitalLetter&gt;False&lt;/SA1628DocumentationTextMustBeginWithACapitalLetter&gt;&lt;SA1629DocumentationTextMustEndWithAPeriod&gt;False&lt;/SA1629DocumentationTextMustEndWithAPeriod&gt;&lt;SA1633SA1641UpdateFileHeader&gt;ReplaceAll&lt;/SA1633SA1641UpdateFileHeader&gt;&lt;SA1639FileHeaderMustHaveSummary&gt;False&lt;/SA1639FileHeaderMustHaveSummary&gt;&lt;SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1644DocumentationHeadersMustNotContainBlankLines&gt;False&lt;/SA1644DocumentationHeadersMustNotContainBlankLines&gt;&lt;/StyleCop.Documentation&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSFixBuiltinTypeReferences&gt;True&lt;/CSFixBuiltinTypeReferences&gt;&lt;CSArrangeQualifiers&gt;True&lt;/CSArrangeQualifiers&gt;&lt;CSEnforceVarKeywordUsageSettings&gt;True&lt;/CSEnforceVarKeywordUsageSettings&gt;&lt;CSMakeFieldReadonly&gt;True&lt;/CSMakeFieldReadonly&gt;&lt;CSharpFormatDocComments&gt;True&lt;/CSharpFormatDocComments&gt;&lt;/Profile&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Simple/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Simple"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;CAN_CHANGE_TO_IMPLICIT&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_WHEN_INITIALIZER_HAS_TYPE&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;IMPLICIT_EXCEPT_PRIMITIVE_TYPES&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSUpdateFileHeader&gt;True&lt;/CSUpdateFileHeader&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;StyleCop.Documentation&gt;&lt;SA1600ElementsMustBeDocumented&gt;False&lt;/SA1600ElementsMustBeDocumented&gt;&lt;SA1604ElementDocumentationMustHaveSummary&gt;False&lt;/SA1604ElementDocumentationMustHaveSummary&gt;&lt;SA1609PropertyDocumentationMustHaveValueDocumented&gt;False&lt;/SA1609PropertyDocumentationMustHaveValueDocumented&gt;&lt;SA1611ElementParametersMustBeDocumented&gt;False&lt;/SA1611ElementParametersMustBeDocumented&gt;&lt;SA1615ElementReturnValueMustBeDocumented&gt;False&lt;/SA1615ElementReturnValueMustBeDocumented&gt;&lt;SA1617VoidReturnValueMustNotBeDocumented&gt;False&lt;/SA1617VoidReturnValueMustNotBeDocumented&gt;&lt;SA1618GenericTypeParametersMustBeDocumented&gt;False&lt;/SA1618GenericTypeParametersMustBeDocumented&gt;&lt;SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;False&lt;/SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;&lt;SA1628DocumentationTextMustBeginWithACapitalLetter&gt;False&lt;/SA1628DocumentationTextMustBeginWithACapitalLetter&gt;&lt;SA1629DocumentationTextMustEndWithAPeriod&gt;False&lt;/SA1629DocumentationTextMustEndWithAPeriod&gt;&lt;SA1633SA1641UpdateFileHeader&gt;ReplaceAll&lt;/SA1633SA1641UpdateFileHeader&gt;&lt;SA1639FileHeaderMustHaveSummary&gt;False&lt;/SA1639FileHeaderMustHaveSummary&gt;&lt;SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1644DocumentationHeadersMustNotContainBlankLines&gt;False&lt;/SA1644DocumentationHeadersMustNotContainBlankLines&gt;&lt;/StyleCop.Documentation&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;CSFixBuiltinTypeReferences&gt;True&lt;/CSFixBuiltinTypeReferences&gt;&lt;CSArrangeQualifiers&gt;True&lt;/CSArrangeQualifiers&gt;&lt;CSEnforceVarKeywordUsageSettings&gt;True&lt;/CSEnforceVarKeywordUsageSettings&gt;&lt;CSMakeFieldReadonly&gt;True&lt;/CSMakeFieldReadonly&gt;&lt;CSharpFormatDocComments&gt;True&lt;/CSharpFormatDocComments&gt;&lt;CSArrangeTypeModifiers&gt;True&lt;/CSArrangeTypeModifiers&gt;&lt;CSArrangeTypeMemberModifiers&gt;True&lt;/CSArrangeTypeMemberModifiers&gt;&lt;CSSortModifiers&gt;True&lt;/CSSortModifiers&gt;&lt;/Profile&gt;</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(&quot;Hi {}.&quot;, &quot;there&quot;)
/// </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(&quot;Set {1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);
/// </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(&quot;Set \\{} is not equal to {}.&quot;, &quot;1,2&quot;);
/// </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(&quot;File name is C:\\\\{}.&quot;, &quot;file.zip&quot;);
/// </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(&quot;Hi {}.&quot;, &quot;there&quot;);
/// </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(&quot;Hi {}. My name is {}.&quot;, &quot;Alice&quot;, &quot;Bob&quot;);
/// </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);
}
}
}