ASP.net Core基础(10)使用日志

您所在的位置:网站首页 logging日志 ASP.net Core基础(10)使用日志

ASP.net Core基础(10)使用日志

2023-03-31 07:14| 来源: 网络整理| 查看: 265

在中除了以外,其他的日志提供者都存储日志,例如将日志存储到该服务中,框架已经向用户提供了不少日志提供者,我们还是从最基本的模板来看一下默认已经启用了哪些日志提供者。

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