This commit is contained in:
Jeroen Saey
2026-02-16 07:48:27 +01:00
parent bb767e89f7
commit 8d2157be1a
2 changed files with 150 additions and 87 deletions

View File

@@ -13,8 +13,8 @@
<Copyright>EonaCat (Jeroen Saey)</Copyright> <Copyright>EonaCat (Jeroen Saey)</Copyright>
<PackageTags>EonaCat;Logger;EonaCatLogger;Log;Writer;Jeroen;Saey</PackageTags> <PackageTags>EonaCat;Logger;EonaCatLogger;Log;Writer;Jeroen;Saey</PackageTags>
<PackageIconUrl /> <PackageIconUrl />
<Version>1.7.5</Version> <Version>1.7.6</Version>
<FileVersion>1.7.5</FileVersion> <FileVersion>1.7.6</FileVersion>
<PackageReadmeFile>README.md</PackageReadmeFile> <PackageReadmeFile>README.md</PackageReadmeFile>
<GenerateDocumentationFile>True</GenerateDocumentationFile> <GenerateDocumentationFile>True</GenerateDocumentationFile>
<PackageLicenseFile>LICENSE</PackageLicenseFile> <PackageLicenseFile>LICENSE</PackageLicenseFile>
@@ -25,7 +25,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<EVRevisionFormat>1.7.5+{chash:10}.{c:ymd}</EVRevisionFormat> <EVRevisionFormat>1.7.6+{chash:10}.{c:ymd}</EVRevisionFormat>
<EVDefault>true</EVDefault> <EVDefault>true</EVDefault>
<EVInfo>true</EVInfo> <EVInfo>true</EVInfo>
<EVTagMatch>v[0-9]*</EVTagMatch> <EVTagMatch>v[0-9]*</EVTagMatch>

View File

@@ -42,6 +42,9 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider, IDisposable
private int _position; private int _position;
private long _size; private long _size;
[ThreadStatic]
private static StringBuilder? _cachedStringBuilder;
public string LogFile => _filePath; public string LogFile => _filePath;
private volatile bool _running = true; private volatile bool _running = true;
private readonly int _maxRolloverFiles; private readonly int _maxRolloverFiles;
@@ -131,6 +134,150 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider, IDisposable
FlushFinal(); FlushFinal();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void WriteMessage(LogMessage msg)
{
var sb = AcquireStringBuilder();
if (IncludeCorrelationId)
{
var ctx = _context.GetAll();
var tags = msg.Tags;
if (ctx.Count > 0 || (tags?.Length ?? 0) > 0)
{
sb.Append(" [");
foreach (var kv in ctx)
{
sb.Append(kv.Key).Append('=').Append(kv.Value).Append(' ');
}
if (tags != null)
{
for (int i = 0; i < tags.Length; i++)
{
sb.Append("tag=").Append(tags[i]).Append(' ');
}
}
// Trim trailing space
if (sb[sb.Length -1] == ' ')
{
sb.Length--;
}
sb.Append(']');
}
// Ensure correlation id exists
var correlationId = _context.Get("CorrelationId");
if (correlationId == null)
{
correlationId = Guid.NewGuid().ToString();
_context.Set("CorrelationId", correlationId);
}
}
sb.Append(' ')
.Append(msg.Message)
.AppendLine();
int charCount = sb.Length;
int maxBytes = Utf8.GetMaxByteCount(charCount);
byte[] rented = ArrayPool<byte>.Shared.Rent(maxBytes);
int byteCount = Utf8.GetBytes(sb.ToString(), 0, charCount, rented, 0);
byte[] data = rented;
int length = byteCount;
if (_encryptionEnabled)
{
data = _encryptor.TransformFinalBlock(rented, 0, byteCount);
length = data.Length;
ArrayPool<byte>.Shared.Return(rented, true);
rented = null;
}
WriteToBuffer(data, length);
if (_maxFileSize > 0 && _size >= _maxFileSize)
{
RollFile();
}
if (rented != null)
{
ArrayPool<byte>.Shared.Return(rented, true);
}
ReleaseStringBuilder(sb);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void WriteToBuffer(byte[] data, int length)
{
if (length > BufferSize)
{
if (_position > 0)
{
FlushInternal();
}
WriteDirect(data, length);
return;
}
if (_position + length > BufferSize)
{
FlushInternal();
}
Buffer.BlockCopy(data, 0, _buffer, _position, length);
_position += length;
_size += length;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static StringBuilder AcquireStringBuilder()
{
var sb = _cachedStringBuilder;
if (sb == null)
{
sb = new StringBuilder(256);
_cachedStringBuilder = sb;
}
else
{
sb.Clear();
}
return sb;
}
private const int MaxBuilderCapacity = 8 * 1024;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void ReleaseStringBuilder(StringBuilder sb)
{
if (sb.Capacity > MaxBuilderCapacity)
{
_cachedStringBuilder = new StringBuilder(256);
}
}
private void WriteDirect(byte[] data, int length)
{
_stream.Write(data, 0, length);
_size += length;
if (_maxFileSize > 0 && _size >= _maxFileSize)
{
RollFile();
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void FlushIfNeeded() private void FlushIfNeeded()
{ {
@@ -157,90 +304,6 @@ public sealed class FileLoggerProvider : BatchingLoggerProvider, IDisposable
_stream.Flush(true); _stream.Flush(true);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void WriteMessage(LogMessage msg)
{
StringBuilder sb = new StringBuilder();
if (IncludeCorrelationId)
{
var ctx = _context.GetAll();
if (ctx.Count > 0 || (msg.Tags?.Length ?? 0) > 0)
{
sb.Append(" [");
foreach (var kv in ctx)
{
sb.Append(kv.Key);
sb.Append('=');
sb.Append(kv.Value);
sb.Append(' ');
}
if (msg.Tags != null)
{
for (int i = 0; i < msg.Tags.Length; i++)
{
sb.Append("tag=");
sb.Append(msg.Tags[i]);
sb.Append(' ');
}
}
if (sb[sb.Length - 1] == ' ')
{
sb.Length--;
}
sb.Append(']');
}
}
string correlationId = null;
if (IncludeCorrelationId)
{
correlationId = _context.Get("CorrelationId") ?? Guid.NewGuid().ToString();
_context.Set("CorrelationId", correlationId);
}
string text = sb.ToString() + ' ' + msg.Message + Environment.NewLine;
int max = Utf8.GetMaxByteCount(text.Length);
byte[] temp = ArrayPool<byte>.Shared.Rent(max);
int bytes = Utf8.GetBytes(text, 0, text.Length, temp, 0);
byte[] final = temp;
int length = bytes;
if (_encryptionEnabled)
{
final = _encryptor.TransformFinalBlock(temp, 0, bytes);
length = final.Length;
ArrayPool<byte>.Shared.Return(temp, true);
temp = null;
}
if (_position + length > BufferSize)
{
FlushInternal();
}
Buffer.BlockCopy(final, 0, _buffer, _position, length);
_position += length;
_size += length;
if (_maxFileSize > 0 && _size >= _maxFileSize)
{
RollFile();
}
if (temp != null)
{
ArrayPool<byte>.Shared.Return(temp, true);
}
}
private readonly object _rollLock = new(); private readonly object _rollLock = new();
private void RollFile() private void RollFile()