Skip to content

Commit

Permalink
Merge pull request #26 from dotnet-campus/t/lindexi/LoggerInterpolate…
Browse files Browse the repository at this point in the history
…dStringHandler

尝试减少日志过程中的字符串创建数量
  • Loading branch information
walterlv authored Sep 18, 2024
2 parents 023780c + 7062a5d commit f860e25
Show file tree
Hide file tree
Showing 17 changed files with 329 additions and 10 deletions.
32 changes: 23 additions & 9 deletions dotnetCampus.Logger.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30804.86
# Visual Studio Version 17
VisualStudioVersion = 17.10.35013.160
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Logger", "src\dotnetCampus.Logger\dotnetCampus.Logger.csproj", "{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272}"
ProjectSection(ProjectDependencies) = postProject
Expand All @@ -18,21 +17,23 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{AFB0DF31
Directory.Build.targets = Directory.Build.targets
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggerSample.MainApp", "samples\LoggerSample.MainApp\LoggerSample.MainApp.csproj", "{C282F00B-0C42-491F-AC0D-967407E1C418}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerSample.MainApp", "samples\LoggerSample.MainApp\LoggerSample.MainApp.csproj", "{C282F00B-0C42-491F-AC0D-967407E1C418}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{34E3F27E-C7E2-45D7-8035-53C304F77E2A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggerSample.LoggerDependentLibrary", "samples\LoggerSample.LoggerDependentLibrary\LoggerSample.LoggerDependentLibrary.csproj", "{0A1ACF06-FC64-4B5C-97E9-AA2CC307C899}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerSample.LoggerDependentLibrary", "samples\LoggerSample.LoggerDependentLibrary\LoggerSample.LoggerDependentLibrary.csproj", "{0A1ACF06-FC64-4B5C-97E9-AA2CC307C899}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggerSample.LoggerIndependentLibrary", "samples\LoggerSample.LoggerIndependentLibrary\LoggerSample.LoggerIndependentLibrary.csproj", "{36367E21-BABC-4CC4-891E-CEAF56D66B68}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerSample.LoggerIndependentLibrary", "samples\LoggerSample.LoggerIndependentLibrary\LoggerSample.LoggerIndependentLibrary.csproj", "{36367E21-BABC-4CC4-891E-CEAF56D66B68}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{36852775-3A76-49CF-98CC-3067CE54A5AD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnetCampus.Logger.Tests", "tests\dotnetCampus.Logger.Tests\dotnetCampus.Logger.Tests.csproj", "{D0ACB879-D49B-4ACD-9852-23D0E6D15DDB}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Logger.Tests", "tests\dotnetCampus.Logger.Tests\dotnetCampus.Logger.Tests.csproj", "{D0ACB879-D49B-4ACD-9852-23D0E6D15DDB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dotnetCampus.Logger.Analyzer", "src\dotnetCampus.Logger.Analyzer\dotnetCampus.Logger.Analyzer.csproj", "{77F0A6B5-6C8B-4815-8C1E-4F97C24BFB36}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Logger.Analyzer", "src\dotnetCampus.Logger.Analyzer\dotnetCampus.Logger.Analyzer.csproj", "{77F0A6B5-6C8B-4815-8C1E-4F97C24BFB36}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LoggerSample.LoggerIndependentProject", "samples\LoggerSample.LoggerIndependentProject\LoggerSample.LoggerIndependentProject.csproj", "{E0DE93BF-AE07-4F92-A3FD-F4D661339BE0}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LoggerSample.LoggerIndependentProject", "samples\LoggerSample.LoggerIndependentProject\LoggerSample.LoggerIndependentProject.csproj", "{E0DE93BF-AE07-4F92-A3FD-F4D661339BE0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.Logger.Analyzer.Tests", "tests\dotnetCampus.Logger.Analyzer.Tests\dotnetCampus.Logger.Analyzer.Tests.csproj", "{62456A3B-33BC-475E-BC55-5134CF89127D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -44,6 +45,18 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{62456A3B-33BC-475E-BC55-5134CF89127D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Debug|x64.ActiveCfg = Debug|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Debug|x64.Build.0 = Debug|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Debug|x86.ActiveCfg = Debug|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Debug|x86.Build.0 = Debug|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Release|Any CPU.Build.0 = Release|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Release|x64.ActiveCfg = Release|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Release|x64.Build.0 = Release|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Release|x86.ActiveCfg = Release|Any CPU
{62456A3B-33BC-475E-BC55-5134CF89127D}.Release|x86.Build.0 = Release|Any CPU
{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -133,6 +146,7 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{62456A3B-33BC-475E-BC55-5134CF89127D} = {36852775-3A76-49CF-98CC-3067CE54A5AD}
{C282F00B-0C42-491F-AC0D-967407E1C418} = {34E3F27E-C7E2-45D7-8035-53C304F77E2A}
{0A1ACF06-FC64-4B5C-97E9-AA2CC307C899} = {34E3F27E-C7E2-45D7-8035-53C304F77E2A}
{36367E21-BABC-4CC4-891E-CEAF56D66B68} = {34E3F27E-C7E2-45D7-8035-53C304F77E2A}
Expand Down
1 change: 1 addition & 0 deletions samples/LoggerSample.MainApp/LoggerSample.MainApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<DCUseGeneratedLogger>preferReference</DCUseGeneratedLogger>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ partial class AggregateLoggerBridgeLinker : GILoggerBridgeLinker
/// </summary>
public static AggregateLoggerBridgeLinker Default { get; } = new();

public bool IsEnabled(int logLevel)
{
var logger = _logger ?? GLog.Current;
return logger.IsEnabled((GLogLevel)logLevel);
}

private GILogger? _logger;

/// <summary>
Expand Down
11 changes: 11 additions & 0 deletions src/dotnetCampus.Logger/Bridges/BridgeLogger.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ namespace dotnetCampus.Logging.Bridges;
/// </summary>
internal class BridgeLogger : ILogger
{
public bool IsEnabled(LogLevel logLevel)
{
return
#if NETCOREAPP3_0_OR_GREATER
ILoggerBridge
#else
LoggerBridgeLinker
#endif
.Bridge?.IsEnabled((int)logLevel) ?? false;
}

/// <inheritdoc />
void ILogger.Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
Expand Down
6 changes: 6 additions & 0 deletions src/dotnetCampus.Logger/Bridges/ILoggerBridge.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ namespace dotnetCampus.Logging.Bridges;
/// </summary>
public interface ILoggerBridge
{
bool IsEnabled(int logLevel)

Check warning on line 13 in src/dotnetCampus.Logger/Bridges/ILoggerBridge.g.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'ILoggerBridge.IsEnabled(int)'
#if NETCOREAPP3_0_OR_GREATER
=> true
#endif
;

/// <summary>
/// 写入日志条目。
/// </summary>
Expand Down
10 changes: 10 additions & 0 deletions src/dotnetCampus.Logger/CompositeLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ public LogLevel Level
/// </summary>
public required ImmutableArrayILogger Writers { get; init; }

public bool IsEnabled(LogLevel logLevel)

Check warning on line 32 in src/dotnetCampus.Logger/CompositeLogger.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CompositeLogger.IsEnabled(LogLevel)'
{
if (logLevel < Level)
{
return false;
}

return true;
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)

Check warning on line 42 in src/dotnetCampus.Logger/CompositeLogger.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CompositeLogger.Log<TState>(LogLevel, EventId, TState, Exception?, Func<TState, Exception?, string>)'
{
if (logLevel < Level)
Expand Down
7 changes: 7 additions & 0 deletions src/dotnetCampus.Logger/ILogger.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ namespace dotnetCampus.Logging;
/// </remarks>
public interface ILogger
{
/// <summary>
/// 检查是否已启用给定的日志级别。
/// </summary>
/// <param name="logLevel"></param>
/// <returns></returns>
bool IsEnabled(LogLevel logLevel);

/// <summary>
/// 写入日志条目。
/// </summary>
Expand Down
76 changes: 75 additions & 1 deletion src/dotnetCampus.Logger/Log.g.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#nullable enable

using global::System.Runtime.CompilerServices;
using global::System;
using global::System.Diagnostics.CodeAnalysis;

Expand Down Expand Up @@ -129,4 +130,77 @@ public static void Fatal(string message, Exception? exception = null)
{
Current.Log(LogLevel.Critical, default, message, null, static (s, ex) => s);
}
}

#if NET6_0_OR_GREATER
/// <inheritdoc cref="Trace(string)"/>
public static void Trace(LoggerInterpolatedStringHandler message)
{
if (!Current.IsEnabled(LogLevel.Trace))
{
message.Discard();
return;
}
Trace(message.ToStringAndClear());
}

/// <inheritdoc cref="Debug(string)"/>
public static void Debug(LoggerInterpolatedStringHandler message)
{
if (!Current.IsEnabled(LogLevel.Debug))
{
message.Discard();
return;
}

Debug(message.ToStringAndClear());
}

/// <inheritdoc cref="Info(string)"/>
public static void Info(LoggerInterpolatedStringHandler message)
{
if (!Current.IsEnabled(LogLevel.Information))
{
message.Discard();
return;
}

Info(message.ToStringAndClear());
}

/// <inheritdoc cref="Warn(string,Exception)"/>
public static void Warn(LoggerInterpolatedStringHandler message, Exception? exception = null)
{
if (!Current.IsEnabled(LogLevel.Warning))
{
message.Discard();
return;
}

Warn(message.ToStringAndClear(), exception);
}

/// <inheritdoc cref="Error(string,Exception)"/>
public static void Error(LoggerInterpolatedStringHandler message, Exception? exception = null)
{
if (!Current.IsEnabled(LogLevel.Error))
{
message.Discard();
return;
}

Error(message.ToStringAndClear(), exception);
}

/// <inheritdoc cref="Fatal(string,Exception)"/>
public static void Fatal(LoggerInterpolatedStringHandler message, Exception? exception = null)
{
if (!Current.IsEnabled(LogLevel.Critical))
{
message.Discard();
return;
}

Fatal(message.ToStringAndClear(), exception);
}
#endif
}
37 changes: 37 additions & 0 deletions src/dotnetCampus.Logger/LoggerInterpolatedStringHandler.g.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#if NET6_0_OR_GREATER
using global::System.Runtime.CompilerServices;

namespace dotnetCampus.Logging;

[InterpolatedStringHandler]
public ref struct LoggerInterpolatedStringHandler
{
public LoggerInterpolatedStringHandler(int literalLength, int formattedCount)
{
_handler = new DefaultInterpolatedStringHandler(literalLength, formattedCount);
}

private readonly DefaultInterpolatedStringHandler _handler;

public void AppendLiteral(string s) => _handler.AppendLiteral(s);

public void AppendFormatted<T>(T value) => _handler.AppendFormatted(value);

public void AppendFormatted<T>(T value, string format) => _handler.AppendFormatted(value, format);

public string ToStringAndClear() => _handler.ToStringAndClear();

public override string ToString() => _handler.ToString();

/// <summary>
/// 废弃掉此字符串
/// </summary>
public void Discard()
{
// 这里的 ToStringAndClear 其实只是取其 Clear 的功能
// 暂时先使用 DefaultInterpolatedStringHandler 提供的能力,后续再考虑是否需要优化
_handler.ToStringAndClear();
}
}

#endif
10 changes: 10 additions & 0 deletions src/dotnetCampus.Logger/Writers/ConsoleLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ internal ConsoleLogger(ICoreLogWriter coreWriter, TagFilterManager? tagManager)
/// </summary>
private TagFilterManager? TagManager { get; }

public bool IsEnabled(LogLevel logLevel)
{
if (logLevel < Level)
{
return false;
}

return true;
}

/// <inheritdoc />
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
Expand Down
6 changes: 6 additions & 0 deletions src/dotnetCampus.Logger/Writers/DebugLogger.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ namespace dotnetCampus.Logging.Writers;
/// </summary>
public class DebugLogger(ILogger realLogger) : ILogger
{
public bool IsEnabled(LogLevel logLevel)
{
// 在 debug 模式下,所有日志都是可用的
return true;
}

/// <inheritdoc />
void ILogger.Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
Expand Down
6 changes: 6 additions & 0 deletions src/dotnetCampus.Logger/Writers/MemoryCacheLogger.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ internal class MemoryCacheLogger : ILogger

private readonly System.Collections.Concurrent.ConcurrentQueue<CachedLogItem> _queue = [];

public bool IsEnabled(LogLevel logLevel)
{
// 不知道到时候的真的日志是什么,所以只好全记录了
return true;
}

void ILogger.Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (_realLogger is { } logger)
Expand Down
2 changes: 2 additions & 0 deletions src/dotnetCampus.Logger/Writers/NullLogger.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace dotnetCampus.Logging.Writers;
/// </summary>
internal class NullLogger : ILogger
{
public bool IsEnabled(LogLevel logLevel) => false;

/// <inheritdoc />
void ILogger.Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
Expand Down
2 changes: 2 additions & 0 deletions src/dotnetCampus.Logger/Writers/TraceLogger.g.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace dotnetCampus.Logging.Writers;
/// </summary>
public class TraceLogger(ILogger realLogger) : ILogger
{
public bool IsEnabled(LogLevel logLevel) => true;

/// <inheritdoc />
void ILogger.Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using dotnetCampus.Logger.Generators;

using Microsoft.CodeAnalysis.CSharp;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;

namespace dotnetCampus.Logger.Analyzer.Tests.Generators;

[TestClass]
public class LoggerBridgeGeneratorTest
{
[TestMethod]
public void TestGenerateLoggerBridge()
{
var loggerBridgeGenerator = new LoggerBridgeGenerator();
GeneratorDriver driver = CSharpGeneratorDriver.Create(loggerBridgeGenerator);

var compilation = CSharpCompilation.Create
(
"Test",
syntaxTrees:
[
CSharpSyntaxTree.ParseText
(
"""
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using dotnetCampus.Logging.Attributes;
using dotnetCampus.Logging.Configurations;
using dotnetCampus.Logging.Writers;

namespace LoggerSample.MainApp;

[ImportLoggerBridge<global::LoggerSample.LoggerIndependentLibrary.Logging.ILoggerBridge>]
[ImportLoggerBridge<global::LoggerSample.LoggerIndependentProject.Logging.ILoggerBridge>]
internal partial class LoggerBridgeLinker;
"""
)
],
references:
new[]
{
MetadataReference.CreateFromFile(typeof(LoggerSample.LoggerIndependentProject.SourceReferenceTarget).Assembly.Location),
MetadataReference.CreateFromFile(typeof(LoggerSample.LoggerIndependentLibrary.SourceReferenceTarget).Assembly.Location)
} // 加上整个 dotnet 的基础库
.Concat(MetadataReferenceProvider.GetDotNetMetadataReferenceList())
);

driver = driver.RunGenerators(compilation);
var result = driver.GetRunResult();
Assert.IsNotNull(result);
}
}
Loading

0 comments on commit f860e25

Please sign in to comment.