.NET 中 Logger 常被忽视的方法 BeginScope
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的更多相关文章
- 【python常见面试题】之python 中对list去重的多种方法
在python相关职位的面试过程中,会对列表list的去重进行考察.(注意有时会要求保证去重的顺序性) 1.直观方法 li=[1,2,3,4,5,1,2,3] new_li=[] for i in l ...
- .NET框架设计(常被忽视的框架设计技巧)
阅读目录: 1.开篇介绍 2.元数据缓存池模式(在运行时构造元数据缓存池) 2.1.元数据设计模式(抽象出对数据的描述数据) 2.2.借助Dynamic来改变IOC.AOP动态绑定的问题 2.3.元数 ...
- .NET框架设计—常被忽视的框架设计技巧
阅读目录: 1.开篇介绍 2.元数据缓存池模式(在运行时构造元数据缓存池) 2.1.元数据设计模式(抽象出对数据的描述数据) 2.2.借助Dynamic来改变IOC.AOP动态绑定的问题 2.3.元数 ...
- ASP.NET常被忽视的一些细节
原文:ASP.NET常被忽视的一些细节 前段时间碰到一个问题:为什么在ASP.NET程序中定时器有时候会不工作? 这个问题看起来很奇怪,代码好像也没错,但就是结果与预期不一致. 其实这里是ASP.NE ...
- .NET框架设计—常被忽视的C#设计技巧
.NET框架设计—常被忽视的C#设计技巧 阅读目录: 1.开篇介绍 2.尽量使用Lambda匿名函数调用代替反射调用(走进声明式设计) 3.被忽视的特性(Attribute)设计方式 4.扩展方法让你 ...
- .NET框架设计(常被忽视的C#设计技巧)
阅读目录: 1.开篇介绍 2.尽量使用Lambda匿名函数调用代替反射调用(走进声明式设计) 3.被忽视的特性(Attribute)设计方式 4.扩展方法让你的对象如虎添翼(要学会使用扩展方法的设计思 ...
- 【转载】 .NET框架设计—常被忽视的C#设计技巧
阅读目录: 1.开篇介绍 2.尽量使用Lambda匿名函数调用代替反射调用(走进声明式设计) 3.被忽视的特性(Attribute)设计方式 4.扩展方法让你的对象如虎添翼(要学会使用扩展方法的设计思 ...
- logback中logger详解
前言 logback实践笔记 上一篇主要对root进行了实践总结,现在基于上一篇中的springboot代码环境对logback.xml中的logger来进行实践和自己遇到的坑. logger简介 ...
- 03:git常见报错解决方法
1.1 git常见报错解决方法 1.warning: LF will be replaced by CRLF in .idea/workspace.xml. 参考博客:https://www.cnbl ...
- vc++ 在程序中运行另一个程序的方法
在vc++ 程序中运行另一个程序的方法有三个: WinExec(),ShellExcute()和CreateProcess() 三个SDK函数: WinExec,ShellExecute ,Creat ...
随机推荐
- 知识分享:Air780E软件之UDP应用示例
一.UDP概述 UDP(用户数据报协议,UserDatagramProtocol)是一种无连接的.不可靠的传输层协议,主要用于实现网络中的快速通讯.以下是UDP通讯的主要特点: 1.1 无连接通讯: ...
- 1000+节点、200+集群,Slack如何利用Karpenter降本增效?
原文首发于云妙算 Slack 是一款 AI 工作管理和协作平台.随着业务需求的增长,Slack 对其内部计算编排平台进行了重大改造,以增强可扩展性.提高效率并降低成本.该内部平台的代号为"B ...
- callable结合FutureTask的多线程使用(免打扰模式)
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.ut ...
- pikachu平台暴力破解详解
声明:文章只是起演示作用,所有涉及的网站和内容,仅供大家学习交流,如有任何违法行为,均和本人无关,切勿触碰法律底线. 文章来自个人csdn博客,感兴趣的可以关注一下,https://blog.csdn ...
- 使用 JsonSchema 校验 JSON数据
有时候JSON 数据格式需要校验是否合法,我们可以使用 JsonSchema 来校验数据是否合法. 引入 pom.xml https://json-schema.org/ <dependency ...
- HarmonyOS Next 入门实战 - 基础组件、页面实现
基础组件 常用组件 Text:显示文本内容 Image:显示图片 Button:显示一个按钮 Column: 纵向布局 Row:横向布局 List:列表 各组件的用法 Text("文本组件& ...
- C# 企业微信消息推送对接,实现天气预报推送
C# 企业微信消息推送对接,实现天气预报推送 迷恋自留地 准备工作 需要获取的东西1. 企业Id,2.应用secret 和 应用ID 获取企业id 注册完成后,在我的企业=>企业信息=>最 ...
- uniapp打包apk后位置无法获取(简单)
生成云端证书 使用云端证书的SHA1值申请高德key包名自定义 打包前appid,地图key,云打包包名要和申请地图key的包名一样
- 多段区间的时间滑块slider实现方式
多段区间的时间滑块slider实现方式 写在前面:今天要实现一个尖峰平谷的数据配置,这可一下难倒我了,但是还好互联网上大神云集,感谢各位大神的倾情分享,现在就写下我的感悟,留给看到这篇文章的你 参考链 ...
- 金TECH频道|最近备受关注的“应用重构”到底是什么?
"金TECH频道"旨在为您分享中电金信助力行业数字化转型的最新产品业务动态.技术观点洞察与应用实践案例.让我们在这里,与行业发展同频共振,共筑数字新基石.