- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Asp.Net Core轻松学之利用日志监视进行服务遥测详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
在 Net Core 2.2 中,官方文档表示,对 EventListener 这个日志监视类的内容进行了扩充,同时赋予了跟踪 CoreCLR 事件的权限;通过跟踪 CoreCLR 事件,比如通过跟踪 CoreCLR 事件,可以了解和收集到比如 GC,JIT,ThreadPool,intreop 这些运行时服务的行为;通过使用配置注入,我们将获得一种动态跟踪事件的能力.
1. EventListener 介绍 。
1.1 EventListener 中文直译为:事件侦听器 。
EventListener 位于程序集 System.Diagnostics.Tracing 中,该类提供了一组启用/禁用的方法,按照惯例,先来看一下源代码,了解一下其结构 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
abstract
class
EventListener : IDisposable
{
protected
EventListener();
public
event
EventHandler<EventSourceCreatedEventArgs> EventSourceCreated;
public
event
EventHandler<EventWrittenEventArgs> EventWritten;
protected
static
int
EventSourceIndex(EventSource eventSource);
public
void
DisableEvents(EventSource eventSource);
public
virtual
void
Dispose();
public
void
EnableEvents(EventSource eventSource, EventLevel level);
public
void
EnableEvents(EventSource eventSource, EventLevel level, EventKeywords matchAnyKeyword);
protected
internal
virtual
void
OnEventWritten(EventWrittenEventArgs eventData);
}
|
从类结构中可以看出,EventListener 中的方法并不多,而且从名字都可以推断出其行为, 因为该类是一个抽象类,并不能直接使用,接下来我们创建一个 ReportListener 类继承它 。
2. 创建自定义事件侦听器 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public
class
ReportListener : EventListener
{
public
ReportListener() { }
public
Dictionary<
string
, ListenerItem> Items {
get
;
set
; } =
new
Dictionary<
string
, ListenerItem>();
public
ReportListener(Dictionary<
string
, ListenerItem> items)
{
this
.Items = items;
}
protected
override
void
OnEventSourceCreated(EventSource eventSource)
{
if
(Items.ContainsKey(eventSource.Name))
{
var item = Items[eventSource.Name];
EnableEvents(eventSource, item.Level, item.Keywords);
}
}
protected
override
void
OnEventWritten(EventWrittenEventArgs eventData)
{
if
(Items.ContainsKey(eventData.EventSource.Name))
{
Console.WriteLine($
"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventSource.Name}.{eventData.EventName}"
);
for
(
int
i = 0; i < eventData.Payload.Count; i++)
{
string
payloadString = eventData.Payload[i]?.ToString() ??
string
.Empty;
Console.WriteLine($
"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\""
);
}
Console.WriteLine(
"\n"
);
}
}
}
|
ReportListener 自定义事件侦听器的代码非常简单,只是简单的继承了 EventListener 后,重写了父类的两个方法:创建事件和写入事件 。
同时,还定义了一个公共属性 Dictionary<string, ListenerItem> Items ,该属性接受一个 ListenerItem 的跟踪配置集,通过配置文件注入,动态觉得哪些事件可以被写入到侦听器中 。
3. 配置跟踪项目 。
在配置文件 appsettings.json 中增加以下内容 。
1
2
3
4
5
6
7
8
9
|
{
"listener"
: [
{
"name"
:
"HomeEventSource"
,
"level"
: 5,
"keywords"
: -1
}
]
}
|
配置说明 。
上面的配置文件表示,定义一个事件源对象(EventSource),名称为 HomeEventSource,事件级别(EventLevel)为 5,关键字(EventKeywords)为 -1 。
关于事件级别和事件关键字的值,和系统定义的一致 。
3.1 事件级别定义 。
1
2
3
4
5
6
7
8
9
10
11
12
|
namespace
System.Diagnostics.Tracing
{
public
enum
EventLevel
{
LogAlways = 0,
Critical = 1,
Error = 2,
Warning = 3,
Informational = 4,
Verbose = 5
}
}
|
3.2 事件关键字定义 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
namespace
System.Diagnostics.Tracing
{
[Flags]
public
enum
EventKeywords :
long
{
All = -1,
None = 0,
WdiContext = 562949953421312,
MicrosoftTelemetry = 562949953421312,
WdiDiagnostic = 1125899906842624,
Sqm = 2251799813685248,
AuditFailure = 4503599627370496,
CorrelationHint = 4503599627370496,
AuditSuccess = 9007199254740992,
EventLogClassic = 36028797018963968
}
}
|
3.3 配置文件完全按照系统值定义,为了更好的使用配置文件,我们定义了下面的实体类 。
1
2
3
4
5
6
|
public
class
ListenerItem
{
public
string
Name {
get
;
set
; }
public
EventLevel Level {
get
;
set
; } = EventLevel.Verbose;
public
EventKeywords Keywords {
get
;
set
; } = EventKeywords.All;
}
|
4. 开始使用事件侦听器 。
为了在应用程序中使用事件侦听器,我们需要初始化事件侦听器,你可以初始化多个事件侦听器;但是,每个事件侦听器仅需要初始化一次即可 。
4.1 初始化自定义事件侦听器,在 Startup.cs 文件中加入以下代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public
void
AddEventListener(IServiceCollection services)
{
var listeners =
this
.Configuration.GetSection(
"listener"
).Get<List<ListenerItem>>();
Dictionary<
string
, ListenerItem> dict =
new
Dictionary<
string
, ListenerItem>();
if
(listeners !=
null
)
{
foreach
(var item
in
listeners)
{
dict.Add(item.Name, item);
}
}
var report =
new
ReportListener(dict);
services.AddSingleton<ReportListener>(report);
}
public
void
ConfigureServices(IServiceCollection services)
{
AddEventListener(services);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
|
初始化动作非常简单,仅是从配置文件中读取需要跟踪的项,然后注册到 ReportListener 内部即可,为了演示事件的注册,我们需要创建一个事件源,就像配置文件中的名称 HomeEventSource 。
4.2 创建自定义的事件源对象 。
1
2
3
4
5
6
7
8
9
10
|
public
class
HomeEventSource : EventSource
{
public
static
HomeEventSource Instance =
new
HomeEventSource();
[Event(1001)]
public
void
RequestStart(
string
message) => WriteEvent(1001, message);
[Event(1002)]
public
void
RequestStop(
string
message) => WriteEvent(1002, message);
}
|
自定义事件源 HomeEventSource 继承自 EventSource,我们可无需为该自定义事件源进行显式命名,因为默认将会使用 HomeEventSource 类名进行注册事件 。
现在,我们尝试着 HomeController 去生产一个事件,看看效果 。
5. 生产事件 。
5.1 转到 HomeController,在 HomeController 的 Get 方法中使用 HomeEventSource 生产两个事件 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[Route(
"api/[controller]"
)]
[ApiController]
public
class
HomeController : ControllerBase
{
[HttpGet]
public
ActionResult<IEnumerable<
string
>> Get()
{
HomeEventSource.Instance.RequestStart(
"处理业务开始"
);
var arra =
new
string
[] {
"value1"
,
"value2"
};
HomeEventSource.Instance.RequestStop(
"处理业务结束"
);
return
arra;
}
}
|
5.2 回顾一下自定义事件侦听器 ReportListener 的重写方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
protected
override
void
OnEventSourceCreated(EventSource eventSource)
{
if
(Items.ContainsKey(eventSource.Name))
{
var item = Items[eventSource.Name];
EnableEvents(eventSource, item.Level, item.Keywords);
}
}
protected
override
void
OnEventWritten(EventWrittenEventArgs eventData)
{
if
(Items.ContainsKey(eventData.EventSource.Name))
{
Console.WriteLine($
"ThreadID = {eventData.OSThreadId} ID = {eventData.EventId} Name = {eventData.EventSource.Name}.{eventData.EventName}"
);
for
(
int
i = 0; i < eventData.Payload.Count; i++)
{
string
payloadString = eventData.Payload[i]?.ToString() ??
string
.Empty;
Console.WriteLine($
"\tName = \"{eventData.PayloadNames[i]}\" Value = \"{payloadString}\""
);
}
Console.WriteLine(
"\n"
);
}
}
|
由于我们做配置文件中指定了必须是 HomeEventSource 事件源才启用事件,所以上面的代码表示,当一个 HomeEventSource 事件进入的时候,将事件的内容打印到控制台,实际应用中,你可以将这些信息推送到日志订阅服务器,以方便跟踪和汇总 。
5.3 运行程序,看看输出结果如何 。
可以看到,事件生产成功,实际上,CoreCLR 内部生产了非常多的事件,下面我们尝试启用以下 3 个事件源,预期将会收到大量的事件信息 。
5.4 尝试更多事件源 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
protected
override
void
OnEventSourceCreated(EventSource eventSource)
{
if
(eventSource.Name.Equals(
"Microsoft-Windows-DotNETRuntime"
))
{
EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.AuditFailure);
}
else
if
(eventSource.Name.Equals(
"System.Data.DataCommonEventSource"
))
{
EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.AuditFailure);
}
else
if
(eventSource.Name.Equals(
"Microsoft-AspNetCore-Server-Kestrel"
))
{
EnableEvents(eventSource, EventLevel.Verbose, EventKeywords.AuditFailure);
}
}
|
5.5 再次运行程序,看下图输出结果 。
从图中可以看出,这次我们跟踪到了 Microsoft-AspNetCore-Server-Kestrel 事件源生产的开始和结束连接事件 。
结束语 。
示例代码下载:Ron.ListenerDemo.rar 。
总结 。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:https://www.cnblogs.com/viter/p/10128637.html 。
最后此篇关于Asp.Net Core轻松学之利用日志监视进行服务遥测详解的文章就讲到这里了,如果你想了解更多关于Asp.Net Core轻松学之利用日志监视进行服务遥测详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
主要思想是将 EF Core nuget 包添加到 .NET Core 库项目,然后在一堆应用程序(例如 ASP.NET Core、Win 服务、控制台应用程序)中使用该库,而无需在每个应用程序中配置
我想要实现的是编写一个简单的.net核心后台工作程序(.net core 3.1)的代码,在该工作程序作为Windows服务运行时,我在其中将数据写入SQL Server数据库(通过EF Core 3
关于 .Net Core SDK download page 二进制文件有什么用?它与安装程序有何不同? 最佳答案 二进制文件是 .NET Core 的编译代码。它们拥有运行 .NET Core 所需
.NET Core 和 Entity Framework Core 之间的区别?我们可以在 .NET Core 中使用 Entity Framework Core 吗?两者都有什么优势? 最佳答案 E
.NET Core 和 ASP.NET Core 到底有什么区别? 它们是相互排斥的吗?我听说 ASP.NET Core 是基于 .NET Core 构建的,但它也可以基于完整的 .NET 框架构建。
我对 ASP.NET Core 开发完全陌生。我正在尝试使用单个模型和 mysql 创建一个简单的 asp.net core Web api 来存储模型数据,然后我想使用 Swagger 将其作为 R
.NET Core 和 Entity Framework Core 之间的区别?我们可以在 .NET Core 中使用 Entity Framework Core 吗?两者都有什么优势? 最佳答案 E
好吧,作为一个新的 .net 开发生态系统,我有点迷失在核心工具、版本等方面。 有人可以解释我之间的区别吗 VS 2015 核心工具预览版 x - See here .NET Core/SDK 与否
我已阅读有关如何通过信号器核心集线器从后台服务向客户端发送通知的文档。如何从客户端接收到后台服务的通知? 后台服务应该只是一个单例。 public class Startup { public
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 4年前关闭。 Improve t
非常简单的问题: 我正在尝试创建一个像这样的谓词构建器: var predicate = PredicateBuilder.False(); 但似乎在Net Core和EF Core中不可用。
在 .NET Core 自包含应用程序 中...我们需要在 project.json 中指定运行时 (RID) 我们希望我们的应用程序针对...发布为什么会这样? .NET Core 是跨平台的,与我
如何用 iCloud Core Data 替换我现有的 Core Data?这是我的持久商店协调员: lazy var persistentStoreCoordinator: NSPersistent
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 2 年前。 Improv
今天我正在学习新的 ASP.net 核心 API 3.1,我想将我的旧网站从 MVC4 转移到 Web API。除了一件事,一切都很好。数据库连接。在我的旧网站中,我为每个客户端(10/15 数据库)
我在 Visual Studio 2015 Update 3 和 .NET Core 1.0 中工作。我有一个 .NETCoreApp v1.0 类型的 Web API 项目。当我添加一个 .NET
我一直在尝试遵循 Ben Cull ( http://benjii.me/2016/06/entity-framework-core-migrations-for-class-library-proj
当我打开我的 vs 代码程序时,我收到以下消息: 无法找到 .NET Core SDK。 .NET Core 调试将不会启用。确保 .NET Core SDK 已安装并且在路径上。 如果我安装甚至卸载
我偶然发现了一个非常奇怪的问题。每当 Web 应用程序启动时,dotnet.exe 都会使用相当多的内存(大约 300M)。然而,当它触及某些部分时(我感觉这与 EF Core 使用有关),它会在短时
ASP.NET Core Web (.NET Core) 与 ASP.NET Core Web (.NET Framework) 有什么区别? .NET Framework 是否提供 similar
我是一名优秀的程序员,十分优秀!