Skip to content

Introduce new extended logging model. #4110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
25 changes: 0 additions & 25 deletions bench/Generators/Microsoft.Gen.Logging.PerformanceTests/Log.cs

This file was deleted.

109 changes: 0 additions & 109 deletions bench/Generators/Microsoft.Gen.Logging.PerformanceTests/LogMethod.cs

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,14 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.Telemetry.Logging;
using Microsoft.Shared.Pools;

namespace Microsoft.Gen.Logging.Bench;
namespace Microsoft.Extensions.Telemetry.Bench;

/// <summary>
/// A logger which captures the last log state logged to it.
/// </summary>
internal sealed class MockLogger : ILogger
internal sealed class BenchLogger : ILogger
{
private readonly ObjectPool<List<KeyValuePair<string, object?>>> _listPool = PoolFactory.CreateListPool<KeyValuePair<string, object?>>();

private sealed class Disposable : IDisposable
{
public void Dispose()
Expand All @@ -35,48 +30,45 @@ public void Dispose()
return new Disposable();
}

public bool IsEnabled(LogLevel logLevel)
{
return Enabled;
}

public bool Enabled { get; set; }
public bool IsEnabled(LogLevel logLevel) => true;

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}

switch (state)
{
case LogMethodHelper helper:
case IReadOnlyList<KeyValuePair<string, object?>> l:
{
// this path is optimized in the real Logger implementation, so it is here too...
int count = l.Count;
for (int i = 0; i < count; i++)
{
_ = ProcessItem(l[i]);
}

break;
}

case IEnumerable<KeyValuePair<string, object?>> enumerable:
{
var l = _listPool.Get();

foreach (var e in enumerable)
{
// Any non-primitive value type will be turned into a string on this path.
// But when using the generated code, this conversion to string happens in the
// generated code, which eliminates the overhead of boxing the value type.
if (e.Value is Guid)
{
_ = e.Value.ToString();
}

l.Add(e);
_ = ProcessItem(e);
}

_listPool.Return(l);
break;
}
}
}

private static object? ProcessItem(in KeyValuePair<string, object?> item)
{
var o = item.Value;

if (o?.GetType() == typeof(Guid))
{
// simulate what a real exporter like OTel would do.
o = o.ToString();
}

return o;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.Telemetry.Bench;

internal sealed class BenchLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName) => new BenchLogger();

public void Dispose()
{
// nop
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Microsoft.Extensions.Logging;

namespace Microsoft.Extensions.Telemetry.Bench;

internal static partial class ClassicCodeGen
{
[LoggerMessage(LogLevel.Error, @"Connection id '{connectionId}' received {type} frame for stream ID {streamId} with length {length} and flags {flags} and {other}")]
public static partial void RefTypes(ILogger logger, string connectionId, string type, string streamId, string length, string flags, string other);

[LoggerMessage(LogLevel.Error, @"Range [{start}..{end}], options {options}, guid {guid}")]
public static partial void ValueTypes(ILogger logger, long start, long end, int options, Guid guid);
}
Loading