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

https://nlog-project.org/

<?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");
}
posted on 2023-02-14 14:44  花间岛  阅读(98)  评论(0编辑  收藏  举报