Serilog.Extensions.Logging.File

This package makes it a one-liner - loggerFactory.AddFile() - to configure top-quality file logging for ASP.NET Core apps.

  • Text or JSON file output
  • Files roll over on date; capped file size
  • Request ids and event ids included with each message
  • Writes are performed on a background thread
  • Files are periodically flushed to disk (required for Azure App Service log collection)
  • Fast, stable, battle-proven logging code courtesy of Serilog

You can get started quickly with this package, and later migrate to the full Serilog API if you need more sophisticated log file configuration.

Getting started

1. Add the NuGet package as a dependency of your project either with the package manager or directly to the CSPROJ file:

<PackageReference Include="Serilog.Extensions.Logging.File" Version="2.0.0" />

2. In your Program class, configure logging on the web host builder, and call AddFile() on the provided loggingBuilder.

 Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostingContext, loggingBuilder) =>
{
// loggingBuilder.AddFile("Logs/Logs_{Date}.txt");
loggingBuilder.AddFile(hostingContext.Configuration.GetSection("Logging"));
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});

3. Add a custom excetion filter as a global exception handler:

    public class GlobalExceptionFilter : IExceptionFilter
{
private readonly ILogger<GlobalExceptionFilter> _logger; public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger)
{
_logger = logger;
} public void OnException(ExceptionContext context)
{
var loggingBuilder = new StringBuilder(); if (context.HttpContext.Request.GetDisplayUrl() != null)
loggingBuilder.AppendLine($"\tUrl: {context.HttpContext.Request.GetDisplayUrl()}"); loggingBuilder.AppendLine($"\tIp: {context.HttpContext.Connection.RemoteIpAddress}"); #if DEBUG
foreach (var key in context.HttpContext.Request.Headers.Keys)
{
loggingBuilder.AppendLine($"\t{key}: {context.HttpContext.Request.Headers[key]}");
}
#endif loggingBuilder.AppendLine($"\tError Message: {context.Exception.Message}");
if (context.Exception.InnerException != null)
{
PrintInnerException(context.Exception.InnerException, loggingBuilder);
} loggingBuilder.AppendLine($"\tError HelpLink: {context.Exception.HelpLink}");
loggingBuilder.AppendLine($"\tError StackTrace: {context.Exception.StackTrace}"); _logger.LogError(loggingBuilder.ToString());
} public void PrintInnerException(Exception ex, StringBuilder loggingBuilder)
{
loggingBuilder.AppendLine($"\tError InnerMessage: {ex.Message}");
if (ex.InnerException != null)
{
PrintInnerException(ex.InnerException, loggingBuilder);
}
}
}

4. In your Startup class, configure the global exception handler on the ConfigureServices method, so we can catch all unhandled exceptions:

public void ConfigureServices(IServiceCollection services)
{
... services.AddControllersWithViews(options =>
{
options.Filters.Add<GlobalExceptionFilter>();
}); ...
}
public IActionResult Privacy()
{
throw new Exception("Unhandled exception");
return View();
}

5. In your Startup class, add the log directory as static on the Configure method, so we can view the log directory:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
... app.UseStaticFiles(); //add the log directory as static, so we can view the log directory
app.UseFileServer(new FileServerOptions()
{
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), @"Logs")),
RequestPath = new PathString("/Log"),
EnableDirectoryBrowsing = true
}); app.UseRouting(); ...
}

Done! The framework will inject ILogger instances into controllers and other classes:

class HomeController : Controller
{
readonly ILogger<HomeController> _log; public HomeController(ILogger<HomeController> log)
{
_log = log;
} public IActionResult Index()
{
_logger.LogInformation("Hello, world!");
_logger.LogError(new Exception("Custom exception"), "Custom exception");
}
}

The events will appear in the log file:

2016-10-18T11:14:11.0881912+10:00 0HKVMUG8EMJO9 [INF] Hello, world! (f83bcf75)

File format

By default, the file will be written in plain text. The fields in the log file are:

Field Description Format Example
Timestamp The time the event occurred. ISO-8601 with offset 2016-10-18T11:14:11.0881912+10:00
Request id Uniquely identifies all messages raised during a single web request. Alphanumeric 0HKVMUG8EMJO9
Level The log level assigned to the event. Three-character code in brackets [INF]
Message The log message associated with the event. Free text Hello, world!
Event id Identifies messages generated from the same format string/message template. 32-bit hexadecimal, in parentheses (f83bcf75)
Exception Exception associated with the event. Exception.ToString() format (not shown) System.DivideByZeroException: Attempt to divide by zero\r\n\ at...

To record events in newline-separated JSON instead, specify isJson: true when configuring the logger:

loggingBuilder.AddFile("Logs/myapp-{Date}.txt", isJson: true);

This will produce a log file with lines like:

{"@t":"2016-06-07T03:44:57.8532799Z","@m":"Hello, world!","@i":"f83bcf75","RequestId":"0HKVMUG8EMJO9"}

The JSON document includes all properties associated with the event, not just those present in the message. This makes JSON formatted logs a better choice for offline analysis in many cases.

Rolling

The filename provided to AddFile() should include the {Date} placeholder, which will be replaced with the date of the events contained in the file. Filenames use the yyyyMMdd date format so that files can be ordered using a lexicographic sort:

log-20160631.txt
log-20160701.txt
log-20160702.txt

To prevent outages due to disk space exhaustion, each file is capped to 1 GB in size. If the file size is exceeded, events will be dropped until the next roll point.

Message templates and event ids

The provider supports the templated log messages used by Microsoft.Extensions.Logging. By writing events with format strings or message templates, the provider can infer which messages came from the same logging statement.

This means that although the text of two messages may be different, their event id fields will match, as shown by the two "view" logging statements below:

2016-10-18T11:14:26.2544709+10:00 0HKVMUG8EMJO9 [INF] Running view at "/Views/Home/About.cshtml". (9707eebe)
2016-10-18T11:14:11.0881912+10:00 0HKVMUG8EMJO9 [INF] Hello, world! (f83bcf75)
2016-10-18T11:14:26.2544709+10:00 0HKVMUG8EMJO9 [INF] Running view at "/Views/Home/Index.cshtml". (9707eebe)

Each log message describing view rendering is tagged with (9707eebe), while the "hello" log message is given (f83bcf75). This makes it easy to search the log for messages describing the same kind of event.

Additional configuration

The AddFile() method exposes some basic options for controlling the connection and log volume.

Parameter Description Example value
pathFormat Filename to write. The filename may include {Date} to specify how the date portion of the filename is calculated. May include environment variables. Logs/log-{Date}.txt
minimumLevel The level below which events will be suppressed (the default is LogLevel.Information). LogLevel.Debug
levelOverrides A dictionary mapping logger name prefixes to minimum logging levels.
isJson If true, the log file will be written in JSON format. true
fileSizeLimitBytes The maximum size, in bytes, to which any single log file will be allowed to grow. For unrestricted growth, passnull. The default is 1 GiB. 1024 * 1024 * 1024
retainedFileCountLimit The maximum number of log files that will be retained, including the current log file. For unlimited retention, pass null. The default is 31. 31
outputTemplate The template used for formatting plain text log output. The default is {Timestamp:o} {RequestId,13} [{Level:u3}] {Message} ({EventId:x8}){NewLine}{Exception} {Timestamp:o} {RequestId,13} [{Level:u3}] {Message} {Properties:j} ({EventId:x8}){NewLine}{Exception}

appsettings.json configuration

The file path and other settings can be read from JSON configuration if desired.

In appsettings.json add a "Logging" property:

{
"Logging": {
"PathFormat": "Logs/log-{Date}.txt",
"LogLevel": {
"Default": "Debug",
"Microsoft": "Information"
}
}
}

And then pass the configuration section to the AddFile() method:

loggingBuilder.AddFile(Configuration.GetSection("Logging"));

In addition to the properties shown above, the "Logging" configuration supports:

Property Description Example
Json If true, the log file will be written in JSON format. true
FileSizeLimitBytes The maximum size, in bytes, to which any single log file will be allowed to grow. For unrestricted growth, passnull. The default is 1 GiB. 1024 * 1024 * 1024
RetainedFileCountLimit The maximum number of log files that will be retained, including the current log file. For unlimited retention, pass null. The default is 31. 31
OutputTemplate The template used for formatting plain text log output. The default is {Timestamp:o} {RequestId,13} [{Level:u3}] {Message} ({EventId:x8}){NewLine}{Exception} {Timestamp:o} {RequestId,13} [{Level:u3}] {Message} {Properties:j} ({EventId:x8}){NewLine}{Exception}

Using the full Serilog API

This package is opinionated, providing the most common/recommended options supported by Serilog. For more sophisticated configuration, using Serilog directly is recommened. See the instructions in Serilog.AspNetCore to get started.

The following packages are used to provide AddFile():

ASP.NET Core Logging Solution的更多相关文章

  1. ASP.NET Core Logging in Elasticsearch with Kibana

    在微服务化盛行的今天,日志的收集.分析越来越重要.ASP.NET Core 提供了一个统一的,轻量级的Logining系统,并可以很方便的与第三方日志框架集成.我们也可以根据不同的场景进行扩展,因为A ...

  2. Asp.net core logging 日志

    1 基本概念 Dotnet core 一个重要的特征是 Dependency injection ,中文一般是依赖注入,可以简单理解为一个集合,在应用程序启动时,定义各种具体的实现类型并将其放到集合中 ...

  3. ASP.NET Core 源码学习之 Logging[1]:Introduction

    在ASP.NET 4.X中,我们通常使用 log4net, NLog 等来记录日志,但是当我们引用的一些第三方类库使用不同的日志框架时,就比较混乱了.而在 ASP.Net Core 中内置了日志系统, ...

  4. ASP.NET Core 源码学习之 Logging[3]:Logger

    上一章,我们介绍了日志的配置,在熟悉了配置之后,自然是要了解一下在应用程序中如何使用,而本章则从最基本的使用开始,逐步去了解去源码. LoggerFactory 我们可以在构造函数中注入 ILogge ...

  5. ASP.NET Core 源码学习之 Logging[4]:FileProvider

    前面几章介绍了 ASP.NET Core Logging 系统的配置和使用,而对于 Provider ,微软也提供了 Console, Debug, EventSource, TraceSource ...

  6. 【ASP.NET Core 】ASP.NET Core 源码学习之 Logging[1]:Introduction

    在ASP.NET 4.X中,我们通常使用 log4net, NLog 等来记录日志,但是当我们引用的一些第三方类库使用不同的日志框架时,就比较混乱了.而在 ASP.Net Core 中内置了日志系统, ...

  7. 极简版ASP.NET Core学习路径及教程

    绝承认这是一个七天速成教程,即使有这个效果,我也不愿意接受这个名字.嗯. 这个路径分为两块: 实践入门 理论延伸 有了ASP.NET以及C#的知识以及项目经验,我们几乎可以不再需要了解任何新的知识就开 ...

  8. [转]Using NLog for ASP.NET Core to write custom information to the database

    本文转自:https://github.com/NLog/NLog/issues/1366 In the previous versions of NLog it was easily possibl ...

  9. [转]Setting the NLog database connection string in the ASP.NET Core appsettings.json

    本文转自:https://damienbod.com/2016/09/22/setting-the-nlog-database-connection-string-in-the-asp-net-cor ...

随机推荐

  1. 大前端时代搞定PC/Mac端开发,我有绝招

    如果你是一位前端开发工程师,对"跨平台"一词应该不会感到陌生.像常见的前端框架:比如React.Vue.Angular,它们可以做网页端,也可以做移动端,但很少能做到跨PC.Mac ...

  2. 如果你想写自己的Benchmark框架

    目录 简介 八条军规 第一条军规 第二条军规 第三条军规 第四条军规 第五条军规 第六条军规 第七条军规 最后一条军规 总结 简介 使用过JMH的同学一定会惊叹它的神奇.JMH作为一个优秀的Bench ...

  3. java 面向对象(二十六):枚举类的使用

    1. 枚举类的说明:* 1.枚举类的理解:类的对象只有有限个,确定的.我们称此类为枚举类* 2.当需要定义一组常量时,强烈建议使用枚举类* 3.如果枚举类中只一个对象,则可以作为单例模式的实现方式. ...

  4. 数据可视化之powerBI基础(十八)Power BI度量值的格式如何修改?这里有三种方式

    https://zhuanlan.zhihu.com/p/99818030 ​在知识星球遇到的问题中,有不少朋友问如何修改数值型度量值的格式,比如,新建的度量值如何显示为百分比或者千分位等等,这篇文章 ...

  5. python 面向对象专题(八):特殊方法 (一)__get__、__set__、__delete__ 描述符(一)

    https://www.cnblogs.com/flashBoxer/p/9771797.html 实现了 __get__.__set__ 或 __delete__ 方法的类是描述符.描述符的用法是, ...

  6. (八) SpringBoot起飞之路-整合Shiro详细教程(MyBatis、Thymeleaf)

    兴趣的朋友可以去了解一下前几篇,你的赞就是对我最大的支持,感谢大家! (一) SpringBoot起飞之路-HelloWorld (二) SpringBoot起飞之路-入门原理分析 (三) Sprin ...

  7. 1731: [Usaco2005 dec]Layout 排队布局*

    1731: [Usaco2005 dec]Layout 排队布局 题意: n头奶牛在数轴上,不同奶牛可以在同个位置处,编号小的奶牛必须在前面.m条关系,一种是两头奶牛距离必须超过d,一种是两头奶牛距离 ...

  8. 史上最强vue总结~万字长文---面试开发全靠它了

    vue框架篇 vue的优点 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb: 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习: 双向数据绑定:保留了angular ...

  9. git本地创建分支,并提交到github上去

    很多时候,我们再开发的时候需要分支. 那么怎么在本地创建分支,并提交到github或者是远程仓库中呢? 其实很简单: 第一步: git checkout -b dev     创建新的分支 第二步: ...

  10. Ethical Hacking - NETWORK PENETRATION TESTING(15)

    ARP Poisoning - arpspoof Arpspoof is a tool part of a suit called dsniff, which contains a number of ...