Skip to content

Commit ade156c

Browse files
authored
Merge pull request #17 from dotnet-campus/t/walterlv/filter
Add README.md
2 parents 2a32261 + 27a5421 commit ade156c

File tree

2 files changed

+153
-2
lines changed

2 files changed

+153
-2
lines changed

README.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,155 @@
33
| Build | NuGet |
44
|--|--|
55
|![](https://github.com/dotnet-campus/dotnetCampus.Logger/workflows/.NET%20Core/badge.svg)|[![](https://img.shields.io/nuget/v/dotnetCampus.Logger.svg)](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 个条件的日志

src/dotnetCampus.Logger/Properties/Package/buildTransitive/Package.props

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
解释:
1818
- 所谓优先,指的是生成 global usings 以指定优先级;
1919
-->
20-
<DCUseGeneratedLogger>
21-
</DCUseGeneratedLogger>
20+
<!-- <DCUseGeneratedLogger></DCUseGeneratedLogger> -->
2221
</PropertyGroup>
2322

2423
</Project>

0 commit comments

Comments
 (0)