ASP.net Core基础(10)使用日志 |
您所在的位置:网站首页 › logging日志 › ASP.net Core基础(10)使用日志 |
在中除了以外,其他的日志提供者都存储日志,例如将日志存储到该服务中,框架已经向用户提供了不少日志提供者,我们还是从最基本的模板来看一下默认已经启用了哪些日志提供者。 publicclassProgram { publicstaticvoidMain(string[]args) { CreateHostBuilder(args).Build().Run(); } publicstaticIHostBuilderCreateHostBuilder(string[]args)=> Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder=> { webBuilder.UseStartup(); }); } 我们需要注意的是方法, 在这个方法里,完成了: 创建 调用方法: Console Debug EventSource EventLog: (Windows Only) 以上是默认的日志提供者,如果用户需要自己定制日志,那么可以使用如下的方法: publicstaticIHostBuilderCreateHostBuilder(string[]args)=> Host.CreateDefaultBuilder(args) .ConfigureLogging(logging=> { logging.ClearProviders(); logging.AddConsole(); }) .ConfigureWebHostDefaults(webBuilder=> { webBuilder.UseStartup(); }); 注意扩展方法。 默认配置和基本用法 我们来看一下日志提供者的基本用法,DI在整个框架中都是需要用到的,因此日志也不例外,为了创建日志,我们需要从DI里通过构造函数注入:, 这里有一个重要的概念就是日志的分类(Category), 分类是一个字符串,类似于一个域名的层级形式,除了在日志里记录这个之外,我们还在配置文件里使用该分类,来定义某个分类的日志等级,以过滤日志。 从构造函数里注入,并使用: publicclassAboutModel:PageModel { privatereadonlyILogger_logger; publicAboutModel(ILoggerlogger) { _logger=logger; } publicstringMessage {get;set; } publicvoidOnGet() { Message=$"About page visited at"; _logger.LogInformation(Message); } } 这里有两个非常重要的概念,就是日志的等级,以及日志的分类,关于分类我们上面已经学习过了。 日志配置 我们使用配置来配置日志,同时这个项下面还有很多个子项,例如: { "Logging":{ "LogLevel":{ "Default":"Information", "Microsoft":"Warning", "Microsoft.Hosting.Lifetime":"Information" } } } 从这个配置上可以看出: , , 都是表示日志的分类。 分类 分类应用所有以开头的分类。 同时每个分类的日志等级可以定位不一样的。 缺省的还是由来定义。 如果某一个提供者没有指定相应的配置,那么就会使用 再看一个例子: { "Logging":{ "LogLevel":{// All providers, LogLevel applies to all the enabled providers. "Default":"Error",// Default logging, Error and higher. "Microsoft":"Warning"// All Microsoft* categories, Warning and higher. }, "Debug":{// Debug provider. "LogLevel":{ "Default":"Information",// Overrides preceding LogLevel:Default setting. "Microsoft.Hosting":"Trace"// Debug:Microsoft.Hosting category. } }, "EventSource":{// EventSource provider "LogLevel":{ "Default":"Warning"// All categories of EventSource provider. } } } } 这里的, 就是专门针对日志提供者设定的配置。 上述也可以以这种形式指定: 也可以通过环境变量,例如: 简单的描述一下日志过滤的规则算法: 使用提供者或者提供者的别名,选择所有符合条件的日志,如果没有符合的,则选择空提供者。 从上一步的结果中,选择符合指定分类名的日志,如果没有符合的分类,则选择所有没有指定分类的日志 如果由多条日志被选择,最少用一条 如果全部没选中,则使用 Log Category 日志分类主要的作用是用于日志的过滤,例如在配置里设定某个分类的等级,在日志显示的时候也显示出具体的分类,按照约定一般情况推荐使用类名来表示分类。 基本的用法可以使用泛型版的ILogger: ILogger publicclassPrivacyModel:PageModel { privatereadonlyILogger_logger; publicPrivacyModel(ILoggerlogger) { _logger=logger; } publicvoidOnGet() { _logger.LogInformation("GET Pages.PrivacyModel called."); } } 也可以明确的指定分类名称,这个时候需要使用方法: publicclassContactModel:PageModel { privatereadonlyILogger_logger; publicContactModel(ILoggerFactorylogger) { _logger=logger.CreateLogger("MyCategory"); } publicvoidOnGet() { _logger.LogInformation("GET Pages.ContactModel called."); } Log Level 日志等级这个很好理解,一般情况分成这几类: Trace: 0 Debug: 1 Information: 2 Warning: 3 Error: 4 Critical: 5 None: 6 日志级别从小到大,显示的信息也会越来越窄,Trace(0), 显示最多的信息。注意日志的方法, 类似这样的。 Log Event Id 每个日志都可以指定一个事件的ID, 这里的ID是用户自行定义的,非常方便用自己的系统中,用于快速的判断问题。 publicclassMyLogEvents { publicconstintGenerateItems=1000; publicconstintListItems=1001; publicconstintGetItem=1002; publicconstintInsertItem=1003; publicconstintUpdateItem=1004; publicconstintDeleteItem=1005; publicconstintTestItem=3000; publicconstintGetItemNotFound=4000; publicconstintUpdateItemNotFound=4001; } 使用事件ID [HttpGet("")] publicasyncTaskGetTodoItem(longid) { _logger.LogInformation(MyLogEvents.GetItem,"Getting item ", id); vartodoItem=await_context.TodoItems.FindAsync(id); if(todoItem==null) { _logger.LogWarning(MyLogEvents.GetItemNotFound,"Get() NOT FOUND", id); returnNotFound(); } returnItemToDTO(todoItem); } 可以看到日志显示的方法是: Log Message Template 日志消息中使用命名模板,如下代码所示: [HttpGet("")] publicasyncTaskGetTodoItem(longid) { _logger.LogInformation(MyLogEvents.GetItem,"Getting item ", id); vartodoItem=await_context.TodoItems.FindAsync(id); if(todoItem==null) { _logger.LogWarning(MyLogEvents.GetItemNotFound,"Get() NOT FOUND", id); returnNotFound(); } returnItemToDTO(todoItem); } stringapples=1; stringpears=2; stringbananas=3; _logger.LogInformation("Parameters: , , ", apples, pears, bananas); Log Exception 日志的方法有重载可以直接显示或者存储异常的,如下代码所示: [HttpGet("")] publicIActionResultTestExp(intid) { varrouteInfo=ControllerContext.ToCtxString(id); _logger.LogInformation(MyLogEvents.TestItem, routeInfo); try { if(id==3) { thrownewException("Test exception"); } } catch(Exceptionex) { _logger.LogWarning(MyLogEvents.GetItemNotFound, ex,"TestExp()", id); returnNotFound(); } returnControllerContext.MyDisplayRouteInfo(); } Log Scope Log Scope可以将一组逻辑的操作组织到一起,这个逻辑组可以附加相同的数据到每个日志上,例如: [HttpGet("")] publicasyncTaskGetTodoItem(longid) { TodoItemtodoItem; using(_logger.BeginScope("using block message")) { _logger.LogInformation(MyLogEvents.GetItem,"Getting item ", id); todoItem=await_context.TodoItems.FindAsync(id); if(todoItem==null) { _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get() NOT FOUND", id); returnNotFound(); } } returnItemToDTO(todoItem); } Service中使用Log 在Service中使用构造函数注入日志的实例,可以直接使用的。 高性能日志处理 这个部分的原因我们之前有一个一篇介绍过,具体的做法实际上是用来定义,例如: 先定义一个委托: privatestaticreadonlyAction_indexPageRequested; 然后将这个委托指向指定的委托: _indexPageRequested=LoggerMessage.Define( LogLevel.Information, newEventId(1,nameof(IndexPageRequested)), "GET request for Index page"); 最后使用一个扩展方法来准备调用它: publicstaticvoidIndexPageRequested(thisILoggerlogger) { _indexPageRequested(logger,null); } 在日常使用中使用该扩展方法: publicasyncTaskOnGetAsync() { _logger.IndexPageRequested(); Quotes=await_db.Quotes.AsNoTracking().ToListAsync(); } 日志这个部分可以先介绍到这里了。 往期文章目录: ASP.net Core基础 AzureDeveloper,一个分享和学习Azure技术的好去处,欢迎关注 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |