-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathLoggerExtensions.tt
100 lines (90 loc) · 3.74 KB
/
LoggerExtensions.tt
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
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".g.cs" #>
<#
string[] logLevels = { "Trace", "Debug", "Information", "Warning", "Error", "Critical", null };
string GetTypeName(string logLevel) => logLevel + "LogInterpolatedStringHandler";
string GetMethodName(string logLevel) => "Log" + logLevel;
string GetLogLevel(string logLevel) => logLevel != null ? "LogLevel." + logLevel : "logLevel";
string GetDescription(string logLevel) => logLevel switch
{
"Trace" => "Formats and writes a trace log message.",
"Debug" => "Formats and writes a debug log message.",
"Information" => "Formats and writes an informational log message.",
"Warning" => "Formats and writes a warning log message.",
"Error" => "Formats and writes an error log message.",
"Critical" => "Formats and writes a critical log message.",
_ => "Formats and writes a log message at the specified log level."
};
#>
#nullable enable
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;
namespace Isle.Extensions.Logging;
/// <summary>
/// Provides extensions methods for <see cref="ILogger" /> to enable structured logging using interpolated strings.
/// </summary>
public static class LoggerExtensions
{
private static readonly Func<FormattedLogValuesBase, Exception?, string> _messageFormatter = MessageFormatter;
<# foreach (var logLevel in logLevels) { #>
<# foreach (var withEventId in new[] { false, true }) { #>
<# foreach (var withException in new[] { false, true }) { #>
/// <summary>
/// <#= GetDescription(logLevel) #>
/// </summary>
/// <param name="logger">The <see cref="ILogger" /> to write to.</param>
<#if (logLevel == null) { #>
/// <param name="logLevel">Entry will be written on this level.</param>
<# } #><#if (withEventId) { #>
/// <param name="eventId">The event id associated with the log.</param>
<# } #><#if (withException) { #>
/// <param name="exception">The exception to log.</param>
<# } #>
/// <param name="handler">The interpolated string of the log message.</param>
public static void <#= GetMethodName(logLevel) #>(
this ILogger logger,
<# if (logLevel == null) { #>
LogLevel logLevel,
<# } #>
<# if (withEventId) { #>
EventId eventId,
<# } #>
<# if (withException) { #>
Exception? exception,
<# } #>
[InterpolatedStringHandlerArgument("logger"<#= logLevel == null ? ", \"logLevel\"" : "" #>)] ref <#= GetTypeName(logLevel) #> handler
)
{
if (handler.IsEnabled)
{
Log(logger, <#= GetLogLevel(logLevel) #>, <#= withEventId ? "eventId" : "default" #>, <#= withException ? "exception" : "null" #>, handler.GetFormattedLogValuesAndReset());
}
}
<# } #>
<# } #>
<# } #>
private static void Log(ILogger logger, LogLevel logLevel, EventId eventId, Exception? exception, FormattedLogValuesBase formattedLogValues)
{
logger.Log(logLevel, eventId, formattedLogValues, exception, _messageFormatter);
}
/// <summary>
/// Formats the message and creates a logical operation scope.
/// </summary>
/// <returns>
/// An <see cref="T:System.IDisposable" /> that ends the logical operation scope on dispose.
/// </returns>
/// <example>
/// using(logger.BeginScopeInterpolated($"Processing request from {Address}"))
/// {
/// }
/// </example>
public static IDisposable BeginScopeInterpolated(this ILogger logger, [InterpolatedStringHandlerArgument("logger")] ref ScopeLogInterpolatedStringHandler handler)
{
return logger.BeginScope(handler.GetFormattedLogValuesAndReset());
}
private static string MessageFormatter(FormattedLogValuesBase state, Exception? error) => state.ToString();
}