This repository was archived by the owner on Jan 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy pathLogging.cs
More file actions
110 lines (91 loc) · 3.3 KB
/
Copy pathLogging.cs
File metadata and controls
110 lines (91 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#nullable enable
using Microsoft.Extensions.Logging;
using static Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger;
using System.Collections.Concurrent;
namespace Tests.IQSharp
{
public class UnitTestLoggerConfiguration
{
public int? EventIdFilter { get; set; } = null;
public LogLevel LogLevel { get; set; } = LogLevel.Information;
}
internal class ActionDisposer : IDisposable
{
private readonly Action OnDispose;
public ActionDisposer(Action onDispose)
{
this.OnDispose = onDispose;
}
public void Dispose() =>
OnDispose();
}
/// <summary>
/// Forwards ASP.NET Core logging information to the unit testing
/// harness.
/// </summary>
public class UnitTestLogger : ILogger
{
private UnitTestLoggerConfiguration Config;
private string CategoryName;
private string? CurrentScope = null;
public UnitTestLogger(string categoryName, UnitTestLoggerConfiguration? config = default)
{
this.CategoryName = categoryName;
this.Config = config ?? new UnitTestLoggerConfiguration();
}
public IDisposable BeginScope<TState>(TState state)
{
var oldScope = CurrentScope;
CurrentScope = state?.ToString();
return new ActionDisposer(() => CurrentScope = oldScope);
}
public bool IsEnabled(LogLevel logLevel) =>
logLevel == Config.LogLevel;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
if (Config.EventIdFilter == null || Config.EventIdFilter == eventId)
{
if (CurrentScope != null)
{
LogMessage(
"{0}",
$"[{CurrentScope} | {eventId}: {logLevel} // {CategoryName}] {formatter(state, exception)}"
);
}
else
{
LogMessage(
"{0}",
$"[{eventId}: {logLevel} // {CategoryName}] {formatter(state, exception)}"
);
}
}
}
}
public class UnitTestLogger<T> : UnitTestLogger, ILogger<T>
{
public UnitTestLogger(string? categoryName = null, UnitTestLoggerConfiguration? config = null)
: base(categoryName ?? typeof(T).Name, config)
{
}
}
public sealed class UnitTestLoggerProvider : ILoggerProvider
{
private readonly UnitTestLoggerConfiguration Config;
private readonly ConcurrentDictionary<string, UnitTestLogger> Loggers =
new ConcurrentDictionary<string, UnitTestLogger>();
public UnitTestLoggerProvider(UnitTestLoggerConfiguration config)
{
this.Config = config;
}
public ILogger CreateLogger(string categoryName) =>
Loggers.GetOrAdd(categoryName, name => new UnitTestLogger(name, Config));
public void Dispose() => Loggers.Clear();
}
}