# DotNetCommon.Filelog
**Repository Path**: jackletter/DotNetCommon.Filelog
## Basic Information
- **Project Name**: DotNetCommon.Filelog
- **Description**: 已转移至:https://gitee.com/jackletter/jackletter.microsoft.extensions.logging.file
根据Microsoft.Extensions.Logging.Console改造的本地文件日志输出组件,轻量便捷,运行平台:asp.net core。
- **Primary Language**: C#
- **License**: MIT
- **Default Branch**: master
- **Homepage**: https://gitee.com/jackletter/jackletter.microsoft.extensions.logging.file
- **GVP Project**: No
## Statistics
- **Stars**: 4
- **Forks**: 0
- **Created**: 2021-04-08
- **Last Updated**: 2022-05-24
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# DotNetCommon.Filelog
#### 介绍
根据Microsoft.Extensions.Logging.Console改造的本地文件日志输出组件,轻量便捷,运行平台:asp.net core。
#### 1. 为什么要写这个项目,开源的日志组件不够用吗?
- 第一:微软提供了一个很好的日志输出框架,也提供了基本的控制台输出组件,但没有提供输出到文件的日志组件,很是遗憾;
- 第二:第三方日志组件(如:NLog、Serialog、Log4net)功能虽然比较全,但也引入了其他大量的概念和规则。而对于中小型项目来说,它们仅需要输出日志到本地文件即可,所以在使用的便捷上总是差强人意;
- 第三:第三方日志组件在某些功能上也不尽如人意,比如:是否能将日志消息按照日志类别输出到不同文件中?在程序工作时,是否占用日志文件?是否能排除某个类别的日志文件不输出?
- 第四:练手。
#### 2. 这个项目的特点
- 不引入新的规则概念,不引入额外的配置文件,力求轻量级,所有配置均在```appsetting.json```中实现,默认只需一行代码引入;
- 实现非占用文件式输出, 方便日志文件浏览,其内部文件的输出是基于内存的单线程队列,高并发下不影响主线程运行;
- 提供按照日志类别、级别过滤输出到不同的文件;
- 提供按文件大小滚动输出的功能;
- 提供定时净化日志目录的功能;
#### 3. 这个项目的实现思路
大量参考控制台输出组件的源码(Microsoft.Extensions.Logging.Console)
#### 4. 快速使用
- 第一步: 安装包
```xml
```
- 第二步:修改Program.cs文件,引入组件
```csharp
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders();
loggingBuilder.AddConsole();
//一行代码即可引入
loggingBuilder.AddFile();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
}
```
- 第三步:没有了。
#### 5. 输出效果
引入日志组件后,为了测试输出效果,我们可以新建一个控制器代码如下:
```csharp
[HttpGet]
public string Get()
{
_logger.LogTrace("trace");
_logger.LogDebug("debug");
_logger.LogInformation("info");
_logger.LogWarning("warn");
_logger.LogError("error");
_logger.LogCritical("critical");
using (_logger.BeginScope("测试日志的Scope"))
{
_logger.LogTrace("scope-trace");
_logger.LogDebug("scope-debug");
_logger.LogInformation("scope-info");
_logger.LogWarning("scope-warn");
_logger.LogError("scope-error");
_logger.LogCritical("scope-critical");
}
_logger.LogTrace("Scope已经结束了。。。");
//多行日志
_logger.LogInformation($@"第几次
小明小红
小花小龙圣诞节哦我按实际大地阿斯顿");
_logger.LogInformation($@"hah
小明小红
小花小龙圣诞节哦我按实际大地阿斯顿end");
//throw new Exception("测试异常日志");
return "ok";
}
```
当程序启动并且访问到这个api后,我们将会看到程序目录下多了个文件夹```logs```(如:```bin\Debug\netcoreapp3.1\logs```),它里面的日志文件如下:
```html
app-all-2021-06-09.log 4KB //应用类别的日志都会记录到这里
app-crit-2021-06-09.log 1KB //应用类别中Critical级别的日志都会记录到这里
app-fail-2021-06-09.log 1KB //应用类别中Error级别的日志都会记录到这里
app-info-2021-06-09.log 2KB //应用类别中Information级别的日志都会记录到这里
app-warn-2021-06-09.log 1KB //应用类别中Warning级别的日志都会记录到这里
system/system-2021-06-09.log 1KB //系统类别的日志都会记录到这里
// system/system-2021-06-09.log 内容
[2021-06-09 20:44:52.676]-[info]: Microsoft.Hosting.Lifetime[0]-[threed:1]
Now listening on: https://localhost:5501
[2021-06-09 20:44:52.679]-[info]: Microsoft.Hosting.Lifetime[0]-[threed:1]
Now listening on: http://localhost:5500
[2021-06-09 20:44:52.680]-[info]: Microsoft.Hosting.Lifetime[0]-[threed:1]
Application started. Press Ctrl+C to shut down.
[2021-06-09 20:44:52.680]-[info]: Microsoft.Hosting.Lifetime[0]-[threed:1]
Hosting environment: Development
[2021-06-09 20:44:52.680]-[info]: Microsoft.Hosting.Lifetime[0]-[threed:1]
Content root path: E:\gitee\DotNetCommon.Filelog\samples\SimpleFileLog
//app-warn-2021-06-09.log 内容
[2021-06-09 20:44:53.604]-[warn]: SimpleFileLog.Controllers.HomeController[0]-[threed:11]
=> RequestPath:/home RequestId:0HM9B8HGAQOQF:00000001, SpanId:|85fcc31f-49a39d824a1949ba., TraceId:85fcc31f-49a39d824a1949ba, ParentId: => SimpleFileLog.Controllers.HomeController.Get (SimpleFileLog)
warn
[2021-06-09 20:44:53.604]-[warn]: SimpleFileLog.Controllers.HomeController[0]-[threed:11]
=> RequestPath:/home RequestId:0HM9B8HGAQOQF:00000001, SpanId:|85fcc31f-49a39d824a1949ba., TraceId:85fcc31f-49a39d824a1949ba, ParentId: => SimpleFileLog.Controllers.HomeController.Get (SimpleFileLog) => 测试日志的Scope
scope-warn
```
> 注意:虽然代码中有输出Information级别以下的日志,但由于工程的appsettings.json中的配置导致Debug和Trace级别的日志并没有记录到文件。
>
> ```json
> {
> "Logging": {
> "LogLevel": {
> "Default": "Information", //设置默认类别日志的输出级别
> "Microsoft": "Warning", //设置Microsoft开头的类别日志的输出级别
> "Microsoft.Hosting.Lifetime": "Information" //设置Microsoft.Hosting.Lifetime开头的类别日志的输出级别
> }
> },
> "AllowedHosts": "*"
> }
> ```
> 为了能输出Information级别以下的日志,我们可以调整appsettings.json的配置如下:
> ```json
> {
> "Logging": {
> "LogLevel": {
> "Default": "Trace",
> "Microsoft": "Trace",
> "Microsoft.Hosting.Lifetime": "Trace"
> }
> },
> "AllowedHosts": "*"
> }
> ```
> 如果仅想设置FileLog组件的日志输出级别,也可以如下设置:
> ```json
> {
> "Logging": {
> "LogLevel": {
> "Default": "Information",
> "Microsoft": "Warning",
> "Microsoft.Hosting.Lifetime": "Information"
> },
> "File":{
> "LogLevel": {
> "Default": "Trace",
> "Microsoft": "Trace",
> "Microsoft.Hosting.Lifetime": "Trace"
> }
> }
> },
> "AllowedHosts": "*"
> }
> ```
> 关于日志的类别和级别参考MSDN文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/logging/?view=aspnetcore-5.0#log-level
#### 6. 轻量配置
上面引入FileLog的时候虽然仅使用了```loggingBuilder.AddFile();```一行代码,但FileLog组件也提供了配置的能力,示例如下:
```csharp
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
},
"File": {
"BaseDirectory": ".", //对于需要将日志输出到其他位置的非常有用
"IncludeScopes": true, //表示是否输出日志范围,默认输出
"InternalLogFile": "logs/internal-#datetime{yyyy-MM-dd}#.log",
"AutoClear": { //自动日志净化
"Enable": false,
"ExpireSpan": 0,
"TriggerCount": 200,
"Dirs": [ "logs" ],
"Exts": [ "*.log" ]
},
"EnableDefaultWriters": true,// 是否开启默认的日志输出器,默认开启
"Writers": [
{
"FirstInclude": [ "Microsoft", "System" ],
"Path": "logs/system-#datetime{yyyy-MM-dd}#.log",
"RollingSize": 10485760,
"MinLogLevel": "Trace",
"MaxLogLevel": "None"
},
{
"FirstInclude": [ "*" ],
"Path": "logs/app-#level#-#datetime{yyyy-MM-dd}#.log",
"SecondExclude": [ "Microsoft", "System" ],
"RollingSize": 10485760,
"MinLogLevel": "Trace",
"MaxLogLevel": "None"
},
{
"FirstInclude": [ "*" ],
"Path": "logs/app-all-#datetime{yyyy-MM-dd}#.log",
"SecondExclude": [ "Microsoft", "System" ],
"RollingSize": 10485760,
"MinLogLevel": "Trace",
"MaxLogLevel": "None"
}
]
}
},
"AllowedHosts": "*"
}
```
**配置详解:**
| 配置项 | 含义 | 默认值 |
| ----------------------- | ------------------------------------------------------------ | ---------------------------------------- |
| BaseDirectory | 当配置相对目录时,使用的基目录地址 | AppDomain.CurrentDomain.BaseDirectory |
| IncludeScopes | 是否输出日志作用域,参考:上面示例的输出 | true |
| InternalLogFile | FileLog内部异常时输出的日志位置,支持相对路径和绝对路径 | logs/internal-#datetime{yyyy-MM-dd}#.log |
| AutoClear | 自动净化日志目录配置块,提供定时删除目录下日志文件的功能 | 看下级 |
| AutoClear.Enable | 是否启用自动净化功能 | false |
| AutoClear.ExpireSpan | 过期时间(单位:秒),当文件的创建日期距现在超过了指定秒后才会被删除 | 0,表示永不过期 |
| AutoClear.TriggerCount | 触发目录净化的条件,当FileLog连续输出多少次后才会扫描日志文件 | 200 |
| AutoClear.Dirs | 需要净化的目录列表,净化时采用的是递归算法 | [ "logs" ] |
| AutoClear.Exts | 为防止误删除文件,必须设置日志文件的匹配模式 | [ "*.log" ] |
| EnableDefaultWriters | 是否开启默认的日志输出器,开启后将会生成BaseDirectory/app-xxx.log和BaseDirectory/system/system-xxx.log系列日志 | true |
| Writers | 日志输出器数组,每个writer对应一个日志文件 | 具有三个日志输出器的数组 |
| Writers[].MinLogLevel | 当前Writer最低输出级别(执行时首先检查MinLogLevel和MaxLogLevel) | Trace,即不限制 |
| Writers[].MaxLogLevel | 当前Writer最高输出级别(执行时首先检查MinLogLevel和MaxLogLevel) | None,即不限制 |
| Writers[].FirstInclude | 默认当前Writer不允许输出任何日志类别,通过FirstInclude设置允许的类别 | null |
| Writers[].SecondExclude | 在FirstInclude基础上,设置排除的日志输出类别 | null |
| Writers[].Path | 当前Writer文件的路径,支持相对路径和绝对路径 | null |
| Writers[].RollingSize | 当前Writer文件滚动输出的单文件最大值(字节),滚动示例:xxxx-r2.log | 10485760,即:10M |
> 注意:
>
> - 上面AutoClear.Exts的配置是调用 ```var _files = Directory.GetFiles(_dir, pattern);``` 生效的。
#### 7. 示例工程
[SimpleFileLog](https://gitee.com/jackletter/DotNetCommon.Filelog/tree/master/samples/SimpleFileLog)