【NetCore】08-日志框架

文章目录

    • 1.日志框架-日志框架最佳姿势
    • 2.日志作用域-解决不同请求之间的日志干扰
      • 2.1 作用域场景
    • 3 结构化日志组件Serilog:记录对查询分析友好的日志
      • 3.1 结构化日志的好处
      • 3.2 使用场景举例

1.日志框架-日志框架最佳姿势

  • 引用程序包
  • Microsoft.Extensions.Logging
  • Microsoft.Extensions.Logging.Console
  • Microsoft.Extensions.Logging.Debug
  • Microsoft.Extensions.Logging.TraceSource
// 控制台程序
static void Main(string[] args)
{
    // 读取文件配置 
	IConfigurationBuilder configBuilder = new ConfigurationBuilder();
	configBuilder .AddJsonFile("appsettings.json",optional:false,reloadOnChange:true);
	var config = configBuilder.Build();
	// 将实例注册到容器
	IServiceCollection serviceCollection = new ServiceCollection();
	
	//如果直接这样注册,那么容器将不会管理注册实例的生命周期
	//serviceCollection.AddSingleton< IConfiguration>(config);
	//用工厂模式将配置对象注册到容器管理
	serviceCollection.AddSingleton< IConfiguration>(p=>config);
	
	serviceCollection.AddLogging(builder=>
	{
		builder.AddConfiguration(config.GetSection("Logging"));
		builder.AddConsole();
	});
	
	IServiceProvider service = serviceCollection.BuildServiceProvider();
	// 日志对象获取
	ILoggerFactory loggerFactory = service.GetService< ILoggerFactory>();
	// 创建日志记录器
	var alogger = loggerFactory.CreateLogger("alogger");
	alogger.LogDebug(100,"mess");// 100为定义的事件ID
	alogger.LogInformation("hello");
		
}


// 配置文件
{
	"Logging":{
		"LogLevel":{
			"Default":"Debug",
			"Microsoft":"Warning",
			"Microsoft.Hosting.Lifetime":"Information"
		}
	},
	"Console":{
		"LogLevel":{
			"Default":"Information",
			"Program":"Trace",
			"alogger":"Trace"
		}
	}
}

  • 日志需要避免记录敏感信息,如密码、密码

⑴ alogger.LogInformation(“Message Time is {dateTime}”,DateTime.Now);
⑵ alogger.LogInformation($@“Message Time is {DateTime.Now}”);
如上所示,上述两句代码执行结果是相同的,但是具体执行逻辑是不同的。
第⑴行代码的字符串拼接是发生在LogInformation内部的Console输出时产生
而第⑵行代码的字符串拼接发生在向LogInformation传递参数之前
如果日志输出级别设置为None时,虽然两行代码的输出都是空,但是第⑴行代码的字符串拼接不会发生,而第⑵行的字符串拼接还是发生了,这是对服务器性能的一个比较大的消耗,这里需要避免

2.日志作用域-解决不同请求之间的日志干扰

2.1 作用域场景

  • 一个事务包含多条操作
  • 复杂流程的日志关联,如工作流流程记录日志
  • 调用链追踪与请求处理过程对应时
static void Main(string[] args)
{
    // 读取文件配置 
	IConfigurationBuilder configBuilder = new ConfigurationBuilder();
	configBuilder.CommandLine(args);
	configBuilder .AddJsonFile("appsettings.json",optional:false,reloadOnChange:true);
	var config = configBuilder.Build();
	
	// 将实例注册到容器
	IServiceCollection serviceCollection = new ServiceCollection();
	//用工厂模式将配置对象注册到容器管理
	serviceCollection.AddSingleton< IConfiguration>(p=>config);
	serviceCollection.AddLogging(builder=>
	{
		builder.AddConfiguration(config.GetSection("Logging"));
		builder.AddConsole();
		builder.AddDebug();// 日志输出到VS调试信息框中
	});
	
	IServiceProvider service = serviceCollection.BuildServiceProvider();
	var logger = service.GetService();
	
	// 如果想要输出ScopeId需要在配置文件中设置IncludeScopes属性为true,如下配置文件所示
	// 配置如果发生修改,会同步热更新
	using(logger.BeginSope("ScopeId:{scopeId}",Guid.NewGuid()))
	{
		logger.LogInformation("Inofo");
		logger.logError("Error");
		logger.LogTrace("Trace");
	}
	
	Console.ReadKey();
}

// 配置文件
{
	"Logging":{
		"LogLevel":{
			"Default":"Debug",
			"Microsoft":"Warning",
			"Microsoft.Hosting.Lifetime":"Information"
		}
	},
	"Console":{
		"IncludeScopes":true,
		"LogLevel":{
			"Default":"Information",
			"Program":"Trace",
			"alogger":"Trace"
		}
	}
}

3 结构化日志组件Serilog:记录对查询分析友好的日志

3.1 结构化日志的好处

  • 易于检索
  • 易于分析统计

3.2 使用场景举例

  • 实现日志告警
  • 实现上下文的关联
  • 实现与追踪系统集成
// asp web程序
//应用程序包 Serilog.AspNetCore

public class Program
{
	// 读取配置
	public static IConfiguration Configuration{get;} = new ConfigurationBuilder()
		.SetBasePath(Directory.GetCurrentDirectory())
		.AddJsonFile("appsetting.json",optional:false,reloadOnChange:true)
		.AddJsonFile($"appsetting.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")??"Production"}.json",optional:false,reoladOnChange:true)
		.AddEnvironmentVariable()
		.Build();		
	
	public static int Main(string[] args)
	{
		// 将配置传递给Serilog的初始化过程
		Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(Configuration)
		.MinimumLevel.Debug()
		.Enrich.FromLogContext()
		.WriteTo.Console(new RenderedCompactJsonFormatter())
		.WriteTo.File(formatter:new CompactJsonFormatter(),"logs\\myapp.txt",rollingInterval:RollingInterval.Day)
		.CreateLogger();

		try
		{
			Log.Infotmation("Start web host");
			CreateHostBuilder(args).Builde().Run();
			return0;
		}catch(Exception ex)
		{
			Log.Fatal(ex,"Host terminated unexpectedly");
			return 1;
		}finally{
			Log.CloseAndFlush();
		}
	}
	
	public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args)
			.ConfigureWebHostDefaults(webBuilder => 
			{
				webBuilder.UseStartup();
			})
			.UserSerilog(dispose:true);
	
}

// 配置文件
{
	"Logging":{
		"LogLevel":{
			"Default":"Debug",
			"Microsoft":"Warning",
			"Microsoft.Hosting.Lifetime":"Information"
		}
	},
	"Serilog":{
		"MinimumLevel":{
			"Default":"Information",
			"Override":{
					"Microsoft":"Error",
					"System":"Information"
			}
		}
	},
	"AlloweHost":"*"
}

你可能感兴趣的:(NetCore,C#,开发语言,.netcore,后端)