Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/v2.0' into v2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
neuecc committed Nov 24, 2023
2 parents a28d249 + 4256835 commit e80366b
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 34 deletions.
11 changes: 5 additions & 6 deletions src/ZLogger.MessagePack/MessagePackZLoggerFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) whe
if ((IncludeProperties & IncludeProperties.ScopeKeyValues) != 0)
{
propCount--;
if (entry.ScopeState != null)
if (entry.LogInfo.ScopeState != null)
{
var scopeProperties = entry.ScopeState.Properties;
var scopeProperties = entry.LogInfo.ScopeState.Properties;
for (var i = 0; i < scopeProperties.Length; i++)
{
if (scopeProperties[i].Key != "{OriginalFormat}")
Expand Down Expand Up @@ -153,12 +153,11 @@ public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) whe
// Scope
if ((flag & IncludeProperties.ScopeKeyValues) != 0)
{
if (entry.ScopeState != null)
if (entry.LogInfo.ScopeState is { Properties: var scopeProperties })
{
var scopeProperties = entry.ScopeState.Properties;
for (var i = 0; i < scopeProperties.Length; i++)
foreach (var t in scopeProperties)
{
var (key, value) = scopeProperties[i];
var (key, value) = t;
// If `BeginScope(format, arg1, arg2)` style is used, the first argument `format` string is passed with this name
if (key == "{OriginalFormat}") continue;

Expand Down
2 changes: 1 addition & 1 deletion src/ZLogger/Formatters/SystemTextJsonZLoggerFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public void FormatLogEntry<TEntry>(IBufferWriter<byte> writer, TEntry entry) whe
// Scope
if ((IncludeProperties & IncludeProperties.ScopeKeyValues) != 0)
{
if (entry.ScopeState is { IsEmpty: false } scopeState)
if (entry.LogInfo.ScopeState is { IsEmpty: false } scopeState)
{
var properties = scopeState.Properties;
for (var i = 0; i < properties.Length; i++)
Expand Down
22 changes: 7 additions & 15 deletions src/ZLogger/LogInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,14 @@

namespace ZLogger;

public readonly struct LogInfo
public readonly struct LogInfo(LogCategory category, Timestamp timestamp, LogLevel logLevel, EventId eventId, Exception? exception, LogScopeState? scopeState)
{
public readonly LogCategory Category;
public readonly Timestamp Timestamp;
public readonly LogLevel LogLevel;
public readonly EventId EventId;
public readonly Exception? Exception;

public LogInfo(LogCategory category, Timestamp timestamp, LogLevel logLevel, EventId eventId, Exception? exception)
{
Category = category;
Timestamp = timestamp;
EventId = eventId;
LogLevel = logLevel;
Exception = exception;
}
public readonly LogCategory Category = category;
public readonly Timestamp Timestamp = timestamp;
public readonly LogLevel LogLevel = logLevel;
public readonly EventId EventId = eventId;
public readonly Exception? Exception = exception;
public readonly LogScopeState? ScopeState = scopeState;
}

public readonly struct LogCategory
Expand Down
24 changes: 23 additions & 1 deletion src/ZLogger/LogScopeState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,20 @@ public sealed class LogScopeState

public bool IsEmpty => properties.Count <= 0;

public ReadOnlySpan<KeyValuePair<string, object?>> Properties => CollectionsMarshal.AsSpan(properties);
public ReadOnlySpan<KeyValuePair<string, object?>> Properties
{
get
{
ValidateVersion();
return CollectionsMarshal.AsSpan(properties);
}
}

readonly List<KeyValuePair<string, object?>> properties = new();

// pool safety token
short version;
short snapshotVersion;

internal static LogScopeState Create(IExternalScopeProvider scopeProvider)
{
Expand All @@ -28,6 +39,7 @@ internal static LogScopeState Create(IExternalScopeProvider scopeProvider)
internal void Return()
{
Clear();
unchecked { version++; }
cache.Enqueue(this);
}

Expand Down Expand Up @@ -55,6 +67,16 @@ void Snapshot(IExternalScopeProvider scopeProvider)
break;
}
}, properties);

snapshotVersion = version;
}

void ValidateVersion()
{
if (version != snapshotVersion)
{
throw new InvalidOperationException("ZLogger scope snapshot version is unmatched. The reason is that ZLogger does not support continued outside ownership of LogInfo.");
}
}
}
}
10 changes: 3 additions & 7 deletions src/ZLogger/ZLoggerEntry.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Buffers;
using System.Text;
using System.Text.Json;
using ZLogger.Internal;

Expand All @@ -9,7 +8,6 @@ namespace ZLogger
public interface IZLoggerEntry : IZLoggerFormattable
{
LogInfo LogInfo { get; }
LogScopeState? ScopeState { get; set; }
void FormatUtf8(IBufferWriter<byte> writer, IZLoggerFormatter formatter);
void Return();
}
Expand All @@ -19,8 +17,6 @@ public sealed class ZLoggerEntry<TState> : IZLoggerEntry, IObjectPoolNode<ZLogge
{
static readonly ObjectPool<ZLoggerEntry<TState>> cache = new();

public LogScopeState? ScopeState { get; set; }

ZLoggerEntry<TState>? next;
ref ZLoggerEntry<TState>? IObjectPoolNode<ZLoggerEntry<TState>>.NextNode => ref next;

Expand Down Expand Up @@ -80,11 +76,11 @@ public void Return()
{
((IReferenceCountable)state).Release();
}

state = default!;

logInfo.ScopeState?.Return();
logInfo = default!;
ScopeState?.Return();
ScopeState = default;

cache.TryPush(this);
}
}
Expand Down
6 changes: 2 additions & 4 deletions src/ZLogger/ZLoggerLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@ public ZLoggerLogger(string categoryName, IAsyncLogProcessor logProcessor, ZLogg

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
var info = new LogInfo(category, new Timestamp(timeProvider), logLevel, eventId, exception);

var scopeState = scopeProvider != null
? LogScopeState.Create(scopeProvider)
: null;

var info = new LogInfo(category, new Timestamp(timeProvider), logLevel, eventId, exception, scopeState);

var entry = state is IZLoggerEntryCreatable
? ((IZLoggerEntryCreatable)state).CreateEntry(info) // constrained call avoiding boxing for value types
: new StringFormatterLogState<TState>(state, exception, formatter).CreateEntry(info); // standard `log`

entry.ScopeState = scopeState;

if (state is IReferenceCountable)
{
((IReferenceCountable)state).Retain();
Expand Down

0 comments on commit e80366b

Please sign in to comment.