Skip to content

Commit

Permalink
Minor stress improvement (#57715)
Browse files Browse the repository at this point in the history
* Log S.N.Quic, pool string builder, shared logs dir

* Addressed feedback

* Updated docker TFM references to 7.0 after branching
  • Loading branch information
ManickaP authored Aug 19, 2021
1 parent 0c90347 commit 1eed512
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 48 deletions.
2 changes: 1 addition & 1 deletion eng/docker/libraries-sdk-aspnetcore.linux.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ ARG CONFIGURATION=Release

ARG COREFX_SHARED_FRAMEWORK_NAME=Microsoft.NETCore.App
ARG ASPNETCORE_SHARED_NAME=Microsoft.AspNetCore.App
ARG SOURCE_COREFX_VERSION=6.0.0
ARG SOURCE_COREFX_VERSION=7.0.0
ARG TARGET_SHARED_FRAMEWORK=/usr/share/dotnet/shared
ARG TARGET_COREFX_VERSION=$DOTNET_VERSION

Expand Down
2 changes: 1 addition & 1 deletion eng/docker/libraries-sdk-aspnetcore.windows.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ARG CONFIGURATION=Release

ARG COREFX_SHARED_FRAMEWORK_NAME=Microsoft.NETCore.App
ARG ASPNETCORE_SHARED_NAME=Microsoft.AspNetCore.App
ARG SOURCE_COREFX_VERSION=6.0.0
ARG SOURCE_COREFX_VERSION=7.0.0
ARG TARGET_SHARED_FRAMEWORK="C:\\Program Files\\dotnet\\shared"
ARG TARGET_COREFX_VERSION=$DOTNET_VERSION

Expand Down
2 changes: 1 addition & 1 deletion eng/docker/libraries-sdk.linux.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ARG ARCH=x64
ARG CONFIGURATION=Release

ARG COREFX_SHARED_FRAMEWORK_NAME=Microsoft.NETCore.App
ARG SOURCE_COREFX_VERSION=6.0.0
ARG SOURCE_COREFX_VERSION=7.0.0
ARG TARGET_SHARED_FRAMEWORK=/usr/share/dotnet/shared
ARG TARGET_COREFX_VERSION=$DOTNET_VERSION

Expand Down
2 changes: 1 addition & 1 deletion eng/docker/libraries-sdk.windows.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ARG ARCH=x64
ARG CONFIGURATION=Release

ARG COREFX_SHARED_FRAMEWORK_NAME=Microsoft.NETCore.App
ARG SOURCE_COREFX_VERSION=6.0.0
ARG SOURCE_COREFX_VERSION=7.0.0
ARG TARGET_SHARED_FRAMEWORK="C:\\Program Files\\dotnet\\shared"
ARG TARGET_COREFX_VERSION=$DOTNET_VERSION

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ COPY . .
# Pulling the msquic Debian package from msquic-ci public pipeline and from a hardcoded build.
# Note that this is a temporary solution until we have properly published Linux packages.
# Also note that in order to update to a newer msquic build, you have update this link.
ARG MSQUIC_PACKAGE=libmsquic_1.6.0_amd64.deb
ARG MSQUIC_PACKAGE=libmsquic_1.7.0_amd64.deb
ARG PACKAGES_DIR=LinuxPackages
RUN wget 'https://dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_apis/build/builds/1266893/artifacts?artifactName=LinuxPackages&api-version=6.0&%24format=zip' -O "$PACKAGES_DIR".zip
RUN wget 'https://dev.azure.com/dnceng/9ee6d478-d288-47f7-aacc-f6e6d082ae6d/_apis/build/builds/1298721/artifacts?artifactName=LinuxPackages&api-version=6.0&%24format=zip' -O "$PACKAGES_DIR".zip
RUN apt-get update
RUN apt-get install unzip
RUN unzip $PACKAGES_DIR.zip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="5.0.9" />
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="System.CommandLine.Experimental" Version="0.3.0-alpha.19577.1" />
<PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.5.4" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Quic" Version="6.0.0-preview.5.21301.17"/>
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Quic" Version="6.0.0-preview.5.21301.17" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Buffers;
using Microsoft.Extensions.ObjectPool;

namespace HttpStress
{
public sealed class LogHttpEventListener : EventListener
{
public const string LogDirectory = "logs";

private int _lastLogNumber = 0;
private FileStream _log;
private Channel<string> _messagesChannel = Channel.CreateUnbounded<string>();
private Task _processMessages;
private CancellationTokenSource _stopProcessing = new CancellationTokenSource();
private const string LogDirectory = "./clientlog";
private DefaultObjectPool<StringBuilder> _stringBuilderPool = new DefaultObjectPool<StringBuilder>(new StringBuilderPooledObjectPolicy());

private FileStream CreateNextLogFileStream()
{
Expand Down Expand Up @@ -54,44 +56,38 @@ public LogHttpEventListener()

protected override void OnEventSourceCreated(EventSource eventSource)
{
if (eventSource.Name == "Private.InternalDiagnostics.System.Net.Http")
if (eventSource.Name == "Private.InternalDiagnostics.System.Net.Http" ||
eventSource.Name == "Private.InternalDiagnostics.System.Net.Quic")
{
EnableEvents(eventSource, EventLevel.LogAlways);
}
}

private async Task ProcessMessagesAsync()
{
try
{
byte[] buffer = new byte[8192];
var encoding = Encoding.ASCII;
byte[] buffer = new byte[8192];
var encoding = Encoding.ASCII;

int i = 0;
await foreach (string message in _messagesChannel.Reader.ReadAllAsync(_stopProcessing.Token))
int i = 0;
await foreach (string message in _messagesChannel.Reader.ReadAllAsync())
{
if ((++i % 10_000) == 0)
{
if ((++i % 10_000) == 0)
{
await RotateFiles();
}
int maxLen = encoding.GetMaxByteCount(message.Length);
if (maxLen > buffer.Length)
{
buffer = new byte[maxLen];
}
int byteCount = encoding.GetBytes(message, buffer);

await _log.WriteAsync(buffer.AsMemory(0, byteCount), _stopProcessing.Token);
await RotateFiles();
}
}
catch (OperationCanceledException)
{
return;
int maxLen = encoding.GetMaxByteCount(message.Length);
if (maxLen > buffer.Length)
{
buffer = new byte[maxLen];
}
int byteCount = encoding.GetBytes(message, buffer);

await _log.WriteAsync(buffer.AsMemory(0, byteCount));
}

async ValueTask RotateFiles()
{
await _log.FlushAsync(_stopProcessing.Token);
await _log.FlushAsync();
// Rotate the log if it reaches 50 MB size.
if (_log.Length > (100 << 20))
{
Expand All @@ -101,11 +97,9 @@ async ValueTask RotateFiles()
}
}

private StringBuilder? _cachedStringBuilder;

protected override async void OnEventWritten(EventWrittenEventArgs eventData)
{
StringBuilder sb = Interlocked.Exchange(ref _cachedStringBuilder, null) ?? new StringBuilder();
StringBuilder sb = _stringBuilderPool.Get();
sb.Append($"{eventData.TimeStamp:HH:mm:ss.fffffff}[{eventData.EventName}] ");
for (int i = 0; i < eventData.Payload?.Count; i++)
{
Expand All @@ -116,21 +110,16 @@ protected override async void OnEventWritten(EventWrittenEventArgs eventData)
sb.Append(eventData.PayloadNames?[i]).Append(": ").Append(eventData.Payload[i]);
}
sb.Append(Environment.NewLine);
string s = sb.ToString();
sb.Clear();
Interlocked.Exchange(ref _cachedStringBuilder, sb);
await _messagesChannel.Writer.WriteAsync(s, _stopProcessing.Token);
await _messagesChannel.Writer.WriteAsync(sb.ToString());
_stringBuilderPool.Return(sb);
}

public override void Dispose()
{
base.Dispose();
_log.Flush();
if (!_processMessages.Wait(TimeSpan.FromSeconds(30)))
{
_stopProcessing.Cancel();
_processMessages.Wait();
}
_messagesChannel.Writer.Complete();
_processMessages.Wait();
_log.Dispose();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public void Stop()
}
_stopwatch.Stop();
_cts.Dispose();
_eventListener?.Dispose();
}

public void PrintFinalReport()
Expand All @@ -125,7 +126,6 @@ public void PrintFinalReport()
public void Dispose()
{
Stop();
_eventListener?.Dispose();
}

private async Task InitializeClient()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,12 @@ void ConfigureListenOptions(ListenOptions listenOptions)
LoggerConfiguration loggerConfiguration = new LoggerConfiguration();
if (configuration.Trace)
{
if (!Directory.Exists(LogHttpEventListener.LogDirectory))
{
Directory.CreateDirectory(LogHttpEventListener.LogDirectory);
}
// Clear existing logs first.
foreach (var filename in Directory.GetFiles(".", "server*.log"))
foreach (var filename in Directory.GetFiles(LogHttpEventListener.LogDirectory, "server*.log"))
{
try
{
Expand All @@ -138,7 +142,7 @@ void ConfigureListenOptions(ListenOptions listenOptions)

loggerConfiguration = loggerConfiguration
// Output diagnostics to the file
.WriteTo.File("server.log", fileSizeLimitBytes: 50 << 20, rollOnFileSizeLimit: true)
.WriteTo.File(Path.Combine(LogHttpEventListener.LogDirectory, "server.log"), fileSizeLimitBytes: 100 << 20, rollOnFileSizeLimit: true)
.MinimumLevel.Debug();
}
if (configuration.LogAspNet)
Expand Down

0 comments on commit 1eed512

Please sign in to comment.