|
3 | 3 | | Build | NuGet |
|
4 | 4 | |--|--|
|
5 | 5 | ||[](https://www.nuget.org/packages/dotnetCampus.Logger)|
|
| 6 | + |
| 7 | +## 入门 |
| 8 | + |
| 9 | +### 安装日志库 |
| 10 | + |
| 11 | +在你的项目中安装 `dotnetCampus.Logger` 包,你可以通过 NuGet 包管理器或者通过命令行来安装: |
| 12 | + |
| 13 | +```shell |
| 14 | +dotnet add package dotnetCampus.Logger |
| 15 | +``` |
| 16 | + |
| 17 | +安装完成后,你可以在项目中设置属性来决定如何使用日志库: |
| 18 | + |
| 19 | +```xml |
| 20 | +<PropertyGroup> |
| 21 | + <!-- 设置以源生成器的方式来使用日志库。 --> |
| 22 | + <!-- 以此方式使用日志库,不会使你的项目产生任何额外的依赖,特别适合用于不希望引入额外依赖的库项目。 --> |
| 23 | + <DCUseGeneratedLogger>true</DCUseGeneratedLogger> |
| 24 | +</PropertyGroup> |
| 25 | +``` |
| 26 | + |
| 27 | +这个属性可选的值有: |
| 28 | + |
| 29 | +- `onlySource`: 只使用源生成器日志系统,不会引用库; |
| 30 | +- `preferSource`: 使用源生成器日志系统,并优先使用它; |
| 31 | +- `preferReference`: 使用源生成器日志系统,但优先使用引用的库; |
| 32 | +- `onlyReference`: 只使用引用的库,不会生成源代码; |
| 33 | +- `true`: 只使用源生成器日志系统,不会引用库(其含义与 `onlySource` 等同); |
| 34 | +- `false`: 只使用引用的库,不会生成源代码(其含义与 `onlyReference` 等同)。 |
| 35 | + |
| 36 | +在库中,合适的值为 `onlySource` 以不引入依赖;在产品项目中,合适的值为 `onlyReference`,以使用全功能的日志库。 |
| 37 | + |
| 38 | +在产品的入口项目中,既可以使用 `onlyReference` 也可以使用 `preferReference`。前者允许你以常规的方式使用日志库,而后者则允许你在初始化日志库之前使用日志库。 |
| 39 | + |
| 40 | +### 初始化 |
| 41 | + |
| 42 | +在你的初始化代码中添加如下代码,即可完成日志的配置和初始化: |
| 43 | + |
| 44 | +```csharp |
| 45 | +new LoggerBuilder() |
| 46 | + .WithLevel(LogLevel.Debug) |
| 47 | + .AddWriter(new ConsoleLogger()) |
| 48 | + .Build() |
| 49 | + .IntoGlobalStaticLog(); |
| 50 | +``` |
| 51 | + |
| 52 | +在使用上述方法完成初始化之后,你就可以在任何地方使用 `Log` 类来输出日志了: |
| 53 | + |
| 54 | +```csharp |
| 55 | +Log.Info("Hello, world!"); |
| 56 | +``` |
| 57 | + |
| 58 | +`Log` 静态类提供了多种方法来输出日志: |
| 59 | + |
| 60 | +```csharp |
| 61 | +// 这些日志仅在代码开启了 TRACE 条件编译符的情况下才会编译。 |
| 62 | +Log.TraceLogger.Trace("[SourceReference] Log.Trace.Trace"); |
| 63 | +Log.TraceLogger.Debug("[SourceReference] Log.Trace.Debug"); |
| 64 | +Log.TraceLogger.Info("[SourceReference] Log.Trace.Info"); |
| 65 | +Log.TraceLogger.Warn("[SourceReference] Log.Trace.Warn"); |
| 66 | +Log.TraceLogger.Error("[SourceReference] Log.Trace.Error"); |
| 67 | +Log.TraceLogger.Fatal("[SourceReference] Log.Trace.Fatal"); |
| 68 | + |
| 69 | +// 这些日志仅在代码开启了 DEBUG 条件编译符的情况下才会编译。 |
| 70 | +Log.DebugLogger.Trace("[SourceReference] Log.Debug.Trace"); |
| 71 | +Log.DebugLogger.Debug("[SourceReference] Log.Debug.Debug"); |
| 72 | +Log.DebugLogger.Info("[SourceReference] Log.Debug.Info"); |
| 73 | +Log.DebugLogger.Warn("[SourceReference] Log.Debug.Warn"); |
| 74 | +Log.DebugLogger.Error("[SourceReference] Log.Debug.Error"); |
| 75 | +Log.DebugLogger.Fatal("[SourceReference] Log.Debug.Fatal"); |
| 76 | + |
| 77 | +// 这些日志在任何情况下都会被编译。 |
| 78 | +Log.Trace("[SourceReference] Log.Trace"); |
| 79 | +Log.Debug("[SourceReference] Log.Debug"); |
| 80 | +Log.Info("[SourceReference] Log.Info"); |
| 81 | +Log.Warn("[SourceReference] Log.Warn"); |
| 82 | +Log.Error("[SourceReference] Log.Error"); |
| 83 | +Log.Fatal("[SourceReference] Log.Fatal"); |
| 84 | + |
| 85 | +// 这些方法与上面的方法等价。 |
| 86 | +// 主要用途为你可以通过 Log.Current 拿到一个 ILogger 的实例,用来接入项目的其他部分。 |
| 87 | +Log.Current.Trace("[SourceReference] Log.Current.Trace"); |
| 88 | +Log.Current.Debug("[SourceReference] Log.Current.Debug"); |
| 89 | +Log.Current.Info("[SourceReference] Log.Current.Info"); |
| 90 | +Log.Current.Warn("[SourceReference] Log.Current.Warn"); |
| 91 | +Log.Current.Error("[SourceReference] Log.Current.Error"); |
| 92 | +Log.Current.Fatal("[SourceReference] Log.Current.Fatal"); |
| 93 | +``` |
| 94 | + |
| 95 | +对于复杂的大型项目,可能会有更加丰富的需求,可以参考下面的示例代码: |
| 96 | + |
| 97 | +```csharp |
| 98 | +using dotnetCampus.Logging.Attributes; |
| 99 | +using dotnetCampus.Logging.Writers; |
| 100 | + |
| 101 | +namespace dotnetCampus.Demo.Sample; |
| 102 | + |
| 103 | +internal static class LoggerStartup |
| 104 | +{ |
| 105 | + public static AppBuilder WithLogger(this AppBuilder builder, string[] args) |
| 106 | + { |
| 107 | + new LoggerBuilder() |
| 108 | + // 在日志初始化之前也可以使用日志系统,这些日志会缓存到内存中,直到日志系统初始化完成后再使用。 |
| 109 | + .WithMemoryCache() |
| 110 | + // 设置日志级别为 Debug。 |
| 111 | + .WithLevel(LogLevel.Debug) |
| 112 | + // 添加一个控制台日志写入器,这样控制台里就可以看到日志输出了。 |
| 113 | + .AddWriter(new ConsoleLogger() |
| 114 | + .FilterConsoleTagsFromCommandLineArgs(args)) |
| 115 | + // 如果有一些库使用了本日志框架(使用源生成器,不带依赖的那种),那么可以通过这个方法将它们的日志桥接到本日志框架中。 |
| 116 | + .AddBridge(LoggerBridgeLinker.Default) |
| 117 | + // 初始化日志系统。 |
| 118 | + .Build() |
| 119 | + // 将初始化的日志系统设置到静态全局的 Log 类中,这样就可以在任何地方使用 Log 类来输出日志了。 |
| 120 | + .IntoGlobalStaticLog(); |
| 121 | + return builder; |
| 122 | + } |
| 123 | +} |
| 124 | + |
| 125 | +[ImportLoggerBridge<global::dotnetCampus.Demo1.Logging.ILoggerBridge>] |
| 126 | +[ImportLoggerBridge<global::dotnetCampus.Demo2.Logging.ILoggerBridge>] |
| 127 | +internal partial class LoggerBridgeLinker; |
| 128 | +``` |
| 129 | + |
| 130 | +### 日志过滤规则 |
| 131 | + |
| 132 | +当在命令行中传入 `--log-console-tags TagA,TagB` 时,将进行日志过滤,只输出包含 `TagA` 或 `TagB` 的日志。 |
| 133 | + |
| 134 | +基本规则如下: |
| 135 | + |
| 136 | +1. 可指定单个或多个标签;多个标签之间使用 `,` 或 `;` 分隔,也可以使用空格分隔(但需要注意命令行参数的引号问题)。 |
| 137 | +1. 标签可不带前缀,也可带有 `+` 或 `-` 前缀,分别表示包含、不包含该标签。 |
| 138 | + |
| 139 | +当指定了多个标签时,更详细的规则如下: |
| 140 | + |
| 141 | +1. 先对所有不带前缀的标签进行匹配: |
| 142 | + - 如果没有指定不带前缀的标签,则所有日志都可以进行后续过滤 |
| 143 | + - 如果指定了不带前缀的标签,那么当这些标签中的任何一个能在日志找找到时,这条日志就可以进行后续过滤 |
| 144 | +2. 然后对所有带有 `+` 前缀的标签进行匹配: |
| 145 | + - 如果没有指定带有 `+` 前缀的标签,则前面过滤出来的所有日志都可以进行后续过滤 |
| 146 | + - 如果指定了带有 `+` 前缀的标签,那么当这些标签中的所有标签都能在日志中找到时,这条日志就可以进行后续过滤 |
| 147 | +3. 最后对所有带有 `-` 前缀的标签进行匹配: |
| 148 | + - 如果没有指定带有 `-` 前缀的标签,则前面过滤出来的所有日志都可以进行后续过滤 |
| 149 | + - 如果指定了带有 `-` 前缀的标签,那么当这些标签中的任何一个在日志中找到时,这条日志就在过滤中被排除,排除后剩余的日志才可以进行后续过滤 |
| 150 | +4. 上述 3 个步骤完成之后,过滤出来的日志就是最终输出的日志 |
| 151 | + |
| 152 | +例如,当传入 `--log-console-tags Foo1,Foo2,+Bar1,+Bar2,-Baz1,-Baz2` 时: |
| 153 | + |
| 154 | +1. 只要日志中包含 `Foo1` 或 `Foo2`,就可以进行后续过滤 |
| 155 | +1. 只有当日志中同时包含 `Bar1` 和 `Bar2` 时,才可以进行后续过滤 |
| 156 | +1. 只要日志中包含 `Baz1` 或 `Baz2`,就会被排除在外 |
| 157 | +1. 最终输出的日志是同时满足上述 3 个条件的日志 |
0 commit comments