Updated
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
Reference in New Issue
Block a user