BeginScope 方法是 .NET 中 ILogger 接口的一部分,用于创建日志记录的作用域(Scope)。这种作用域可以将特定的上下文信息包含在日志中,从而提高日志的可读性和调试效率。

配置日志包含作用域信息

首先,需要在日志配置中启用包含作用域信息。以 appsettings.json 为例,以下是配置示例:

{
"Logging": {
"Console": {
"IncludeScopes": true,
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
}

在该配置中,IncludeScopes 被设置为 true,这意味着在控制台日志中将包含作用域信息。

在代码中使用 BeginScope

使用 BeginScope 方法在日志中添加上下文信息,如下代码手动显示:

[HttpGet(Name = "Get")]
public string Get()
{
using (_logger.BeginScope("TenantName {TenantName}", "test"))
{
_logger.LogInformation("这是一条测试日志信息");
} return "ok";
}

在这段代码中,我们使用 BeginScope 创建了一个作用域,并设置了一个上下文变量。在这个作用域之内,日志信息将包含这个上下文变量。

将作用域信息 JSON化

通过实现自己的 ILogger 接口,我们可以将作用域信息以 JSON 格式输出:

public class ScopeLogger : ILogger
{
private readonly string _categoryName;
private static readonly AsyncLocal<Stack<object>> _scopeStack = new AsyncLocal<Stack<object>>(); public ScopeLogger(string categoryName)
{
_categoryName = categoryName;
} public IDisposable BeginScope<TState>(TState state) where TState : notnull
{
if (_scopeStack.Value == null)
{
_scopeStack.Value = new Stack<object>();
}
_scopeStack.Value.Push(state); return new Scope(() => _scopeStack.Value.Pop());
} public bool IsEnabled(LogLevel logLevel) => true; public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
var logEntry = new Dictionary<string, object>
{
["Timestamp"] = DateTime.UtcNow,
["LogLevel"] = logLevel.ToString(),
["Category"] = _categoryName,
["Message"] = formatter(state, exception),
["Exception"] = exception?.ToString()
}; if (_scopeStack.Value != null && _scopeStack.Value.Count > 0)
{
var scopes = new List<object>();
foreach (var scope in _scopeStack.Value)
{
scopes.Add(scope);
}
logEntry["Scopes"] = scopes;
} var json = JsonSerializer.Serialize(logEntry, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);
} private class Scope : IDisposable
{
private readonly Action _onDispose; public Scope(Action onDispose)
{
_onDispose = onDispose;
} public void Dispose()
{
_onDispose?.Invoke();
}
}
} public class ScopeLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
return new ScopeLogger(categoryName);
} public void Dispose() { }
} builder.Logging.ClearProviders();
builder.Logging.AddProvider(new ScopeLoggerProvider());

上面的代码创建了自己的 ILogger 实现,并将作用域信息以 JSON 格式输出。

.NET 中 Logger 常被忽视的方法 BeginScope的更多相关文章

  1. 【python常见面试题】之python 中对list去重的多种方法

    在python相关职位的面试过程中,会对列表list的去重进行考察.(注意有时会要求保证去重的顺序性) 1.直观方法 li=[1,2,3,4,5,1,2,3] new_li=[] for i in l ...

  2. .NET框架设计(常被忽视的框架设计技巧)

    阅读目录: 1.开篇介绍 2.元数据缓存池模式(在运行时构造元数据缓存池) 2.1.元数据设计模式(抽象出对数据的描述数据) 2.2.借助Dynamic来改变IOC.AOP动态绑定的问题 2.3.元数 ...

  3. .NET框架设计—常被忽视的框架设计技巧

    阅读目录: 1.开篇介绍 2.元数据缓存池模式(在运行时构造元数据缓存池) 2.1.元数据设计模式(抽象出对数据的描述数据) 2.2.借助Dynamic来改变IOC.AOP动态绑定的问题 2.3.元数 ...

  4. ASP.NET常被忽视的一些细节

    原文:ASP.NET常被忽视的一些细节 前段时间碰到一个问题:为什么在ASP.NET程序中定时器有时候会不工作? 这个问题看起来很奇怪,代码好像也没错,但就是结果与预期不一致. 其实这里是ASP.NE ...

  5. .NET框架设计—常被忽视的C#设计技巧

    .NET框架设计—常被忽视的C#设计技巧 阅读目录: 1.开篇介绍 2.尽量使用Lambda匿名函数调用代替反射调用(走进声明式设计) 3.被忽视的特性(Attribute)设计方式 4.扩展方法让你 ...

  6. .NET框架设计(常被忽视的C#设计技巧)

    阅读目录: 1.开篇介绍 2.尽量使用Lambda匿名函数调用代替反射调用(走进声明式设计) 3.被忽视的特性(Attribute)设计方式 4.扩展方法让你的对象如虎添翼(要学会使用扩展方法的设计思 ...

  7. 【转载】 .NET框架设计—常被忽视的C#设计技巧

    阅读目录: 1.开篇介绍 2.尽量使用Lambda匿名函数调用代替反射调用(走进声明式设计) 3.被忽视的特性(Attribute)设计方式 4.扩展方法让你的对象如虎添翼(要学会使用扩展方法的设计思 ...

  8. logback中logger详解

    前言 logback实践笔记 ​ 上一篇主要对root进行了实践总结,现在基于上一篇中的springboot代码环境对logback.xml中的logger来进行实践和自己遇到的坑. logger简介 ...

  9. 03:git常见报错解决方法

    1.1 git常见报错解决方法 1.warning: LF will be replaced by CRLF in .idea/workspace.xml. 参考博客:https://www.cnbl ...

  10. vc++ 在程序中运行另一个程序的方法

    在vc++ 程序中运行另一个程序的方法有三个: WinExec(),ShellExcute()和CreateProcess() 三个SDK函数: WinExec,ShellExecute ,Creat ...

随机推荐

  1. 数据结构之链表篇(单链表,循环链表,双向链表)C语言版

    1.链表 链表是线性表的一种,由一系列节点(结点)组成,每个节点包含一个数据域和一个指向下一个节点的指针域.链表结构可以克服数组需要预先知道数据大小的缺点,而且插入和删除元素很方便,但是失去数组随机读 ...

  2. 零基础入门Hadoop:IntelliJ IDEA远程连接服务器中Hadoop运行WordCount

    今天我们来聊一聊大数据,作为一个Hadoop的新手,我也并不敢深入探讨复杂的底层原理.因此,这篇文章的重点更多是从实际操作和入门实践的角度出发,带领大家一起了解大数据应用的基本过程.我们将通过一个经典 ...

  3. 基站定位与Wi-Fi定位?看这篇就够了

    ​ 同学们纷纷发出需求,要求特别讲解Air780EP模组AT开发基站定位与Wi-Fi定位应用示例. 本文同样适用于以下型号:Air700ECQ/Air700EAQ/Air700EMQAir780EQ/ ...

  4. 6、oracle网络(监听)

    oracle包含 1.软件 2.数据库 3.实例 4.监听(listener) 监听的特点 可以独立启动,就是说,数据库没有启动,监听可以启动:数据库启动,监听也可以不启动:数据库启动,监听也启动 监 ...

  5. Ubuntu 无法播放MP4

    今天用ubuntu打开mp4发现无法播放,然后我以为文件损坏了,就传到手机上面,发现还是可以播放的,然后就查了一下相关资料,发现有人让我安装这个 sudo snap install ffmpeg 安装 ...

  6. vue在组件中实现双向绑定

    父组件中的一个变量和子组件的input框实现双向绑定,就要用到下面的方法: 父组件: <script> import CustomInput from './CustomInput.vue ...

  7. mysql5.7之密码重置

    一.windows下更改mysql数据库密码在windows下找到my.ini文件,例如:C:\ProgramData\MySQL\MySQL Server 5.7,打开该文件夹下的my.ini文件, ...

  8. Chrome浏览器本地安装插件

    前情 Chrome是目前世面上很受欢迎的浏览器,你可以通过它的插件扩展功能安装插件优化使用体验和增加功能. 坑位 对于国内受墙影响的用户无法直接通过应用商店安装插件,通过离线安装插件会发现浏览器会提示 ...

  9. cas5配置LDAP的域控验证

    ​pom.xml 在这个下面添加LDAP依赖: <!-- ...Additional dependencies may be placed here... --> <dependen ...

  10. Docker跨主机跨服务器迁移

    ​主要作用: 就是让配置好的容器,可以得到复用,后面用到得的时候就不需要重新配置. 其中涉及到的命令有: docker commit 将容器保存为镜像 docker save -o 将镜像备份为tar ...