Logger
package说明
Microsoft.Extensions.Logging.Abstractions:抽象包,一大堆的接口
Microsoft.Extensions.Logging:提供一些基本的实现
Microsoft.Extensions.Logging.Configuration:支持配置
Microsoft.Extensions.Logging.Console:打印到控制台的实现
基本使用
ILoggingBuilder:日志是基于容器实现的。构建日志的过程就是往容器里添加服务。
内置容器创建
//创建日志工厂,注意这里的设计模式,用到了Factory和Builder模式
ILoggerFactory factory = LoggerFactory.Create(configure =>
{
//configure是ILoggingBuilder用于构建配置Factory
//需要Microsoft.Extensions.Logging.Console的支持
configure.AddConsole(c =>
{
c.FormatterName = ConsoleFormatterNames.Simple;
});
//需要Microsoft.Extensions.Logging.Debug的支持
configure.AddDebug();
//configure.AddFile();//自定义扩展
configure.SetMinimumLevel(LogLevel.Information);
});
//获取一个名为Program的日志实列
//注意:CreateLogger返回的是微软的一个实现,里面做了大量的封装,用于简化你的封装成本。
ILogger<Program> logger1 = factory.CreateLogger<Program>();
//有时候无法使用泛型的使用可以使用这个api
ILogger logger2 = factory.CreateLogger(nameof(Program));
//推荐使用占位符,而不是字符串拼接,因为字符串拼接即使日志不打印,也要拼接即调用ToString,性能不行
logger1.LogInformation("Hello World!{0}", DateTime.Now);//只有打印的时候,才会计算Now并且调用ToString
现有容器创建
public class LoggingBuilder : ILoggingBuilder
{
public IServiceCollection Services { get; }
public LoggingBuilder(IServiceCollection services)
{
Services = services;
}
}
//创建一个容器
var services = new ServiceCollection();
//注册日期工厂和ILogger泛型实现
services.AddLogging();
//创建日志Builder
var loggingBuilder = new LoggingBuilder(services);
//注意loggingBuilder会把服务注册到我们的现有容器里
loggingBuilder.AddConsole();
日志过滤器
ILoggerFactory factory = LoggerFactory.Create(configure =>
{
configure.AddConsole(c =>
{
c.FormatterName = ConsoleFormatterNames.Simple;
});
//作用于所有日志提供程序
configure.AddFilter((categorName, level) =>
{
if (categorName.StartsWith("Microsoft.EntityFramework"))
{
return true;
}
return false;
});
//只作用与指定日志提供程序
//configure.AddFilter<ConsoleLoggerProvider>((categorName, level) =>
//{
// if (categorName.StartsWith("Microsoft.EntityFramework"))
// {
// return true;
// }
// return false;
//});
});
var logger1 = factory.CreateLogger("Microsoft.EntityFramework");
var logger2 = factory.CreateLogger("Microsoft.AspNetCore");
//推荐使用占位符,而不是字符串拼接,因为字符串拼接即使日志不打印,也要拼接,调用toString性能不行
logger1.LogInformation("fff{0}", DateTime.Now);
logger2.LogInformation("fff", DateTime.Now);
日志配置
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Information",
"Microsoft.EntityFramework": "Warning"
},
"Console": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Information",
"Microsoft.EntityFramework": "Information"
}
},
"File": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Information",
"Microsoft.EntityFramework": "Warning"
}
}
}
}
//创建配置
var configuration = new ConfigurationManager();
configuration.SetBasePath(Directory.GetCurrentDirectory());
configuration.AddJsonFile("config.json");
ILoggerFactory factory = LoggerFactory.Create(configure =>
{
//使用配置文件
configure.AddConfiguration(configuration.GetSection("Logging"));
configure.AddConsole(c =>
{
c.FormatterName = ConsoleFormatterNames.Simple;
});
configure.AddFile();
});
factory.CreateLogger("Microsoft.EntityFramework").LogInformation("ef core..");
factory.CreateLogger("Microsoft.AspNetCore").LogInformation("aspnet core..");
factory.CreateLogger("HuaJianDao.Logging").LogInformation("logging..");
自定义
//日志提供程序
//指定提供程序别名:配置时有用
[ProviderAlias("File")]
public class FileLoggerProvider : ILoggerProvider
{
public FileLoggerProvider()
{
}
private LoggerExternalScopeProvider ScopeProvider = new LoggerExternalScopeProvider();
public ILogger CreateLogger(string categoryName)
{
var logger = new FileLogger(categoryName, ScopeProvider);
logger.ScopeProvider = new LoggerExternalScopeProvider();
return logger;
}
public void Dispose()
{
//用于释放资源
}
}
//日志记录器
internal class FileLogger : ILogger
{
private readonly string categoryName;
public IExternalScopeProvider ScopeProvider { get; set; }
public FileLogger(string categoryName, IExternalScopeProvider scopeProvider)
{
this.categoryName = categoryName;
this.ScopeProvider= scopeProvider;
}
public IDisposable BeginScope<TState>(TState state)
{
return ScopeProvider.Push(state);
}
public bool IsEnabled(LogLevel logLevel)
{
return logLevel != LogLevel.None;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
var currentPath = Directory.GetCurrentDirectory();
var path = Path.Combine(currentPath, $"{DateTime.Now:yyyy-MM-dd}.log");
var message = formatter(state,exception);
System.IO.File.AppendAllText(path, $"{logLevel}: {categoryName} {DateTime.Now}\r\n{message}\r\n");
}
}
//文件扩展
public static class FileLoggerExtensions
{
public static ILoggingBuilder AddFile(this ILoggingBuilder builder)
{
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, FileLoggerProvider>());
return builder;
}
}
NLog
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets>
<!--
add your targets here
See https://github.com/nlog/NLog/wiki/Targets for possible targets.
See https://github.com/nlog/NLog/wiki/Layout-Renderers for the possible layout renderers.
-->
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
<target xsi:type="Console" name="c"
layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="f,c" />
</rules>
</nlog>
public static void TestNLog()
{
//https://nlog-project.org/config
ILoggerFactory factory = LoggerFactory.Create(configure =>
{
//使用配置文件
configure.AddNLog();//面向微软的接口编程,可以享受第三方的扩展
configure.AddConsole();
});
var logger = factory.CreateLogger<ILogger<Program>>();
logger.LogInformation("uuuuuuuuuu");
}