DiagnosticSource DiagnosticListener 无侵入式分布式跟踪

这篇具有很好参考价值的文章主要介绍了DiagnosticSource DiagnosticListener 无侵入式分布式跟踪。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ASP.NET Core 中的框架中发出大量诊断事件,包括当前请求进入请求完成事件,HttpClient发出收到与响应,EFCore查询等等。

我们可以利用DiagnosticListener来选择性地监听这些事件,然后通过自己的方式组织这些日志,实现无侵入的分布式跟踪。

下面我们通过DiagnosticSource监听EFCore,与HTTPClient,实现链路追踪。

创建监听

现在我们将配置一个DiagnosticListener来监听全部事件。 

首先,我们需要一个IObserver<DiagnosticListener>,我们将使用它来订阅所有事件。

public class TestDiagnosticObserver : IObserver<DiagnosticListener>
{
    public void OnNext(DiagnosticListener value)
    {
        value.Subscribe(new TestKeyValueObserver());
    }
    public void OnCompleted() { }
    public void OnError(Exception error) { }
}
 
其中重要的方法是OnNext。
然后我们传入另一个自定义类型TestKeyValueObserver,这是实际接收实例发出的事件的类DiagnosticListener。
该事件会接受KeyValuePair<string, object>参数,我们后续可针对此参数做业务相关的筛选。
public class TestKeyValueObserver : IObserver<KeyValuePair<string, object?>>
{
    public void OnNext(KeyValuePair<string, object?> value)
    {
        var activity = Activity.Current;

        Console.WriteLine($"traceId {activity?.TraceId} Received event: {value.Key}");
    }
    public void OnCompleted() { }
    public void OnError(Exception error) { }
}

 

最后一步是在应用程序中注册我们的程序TestDiagnosticObserver。

DiagnosticListener.AllListeners.Subscribe(new TestDiagnosticObserver());

 

创建HTTP请求与EFCore查询

我们新建一个接口,用来集成EF与HttpClient。并调用这个接口查看DiagnosticListener 监听到的内容

[HttpGet]
public async Task<string> GetAsync()
{
    //HTTP
    await _httpClient.GetAsync("https://www.baidu.com");

    //EF
    Item item = new Item()
    {
        Barcode = Guid.NewGuid().ToString(),
        Brand = "Milky Way",
        Name = "Milk",
        PruchasePrice = 20.5,
        SellingPrice = 25.5
    };
    _productsContext.Items.Add(item);
    _productsContext.SaveChanges();
    return "OK";
}

 

调用此接口来看看我们的DiagnosticListener的效果。

可以看到收到了很多Event,包括当前请求的各个阶段,HttpClient的各个阶段,与EFCore查询的各个阶段。

DiagnosticSource DiagnosticListener 无侵入式分布式跟踪

 

解析Event

然后修改TestKeyValueObserver,我们从中挑选我们需要的HTTPClient与EFCore相关的事件。

public class TestKeyValueObserver : IObserver<KeyValuePair<string, object?>>
{
    public void OnNext(KeyValuePair<string, object?> value)
    {
        var activity = Activity.Current;

        //Console.WriteLine($"traceId {activity?.TraceId} Received event: {value.Key}");
        if (value.Key.StartsWith("System.Net.Http.Request"))
        {
            var cEventStr = JsonConvert.SerializeObject(value.Value);
            var cEvent = JsonConvert.DeserializeAnonymousType(cEventStr, new { Request = new { RequestUri = ""} , Timestamp = 2879029490722 });
            Console.WriteLine($"traceId {activity?.TraceId} Request.Start: {cEvent.Timestamp} ");
            Console.WriteLine($"traceId {activity?.TraceId} Request.Uri: {cEvent.Request.RequestUri} ");
        }
        if (value.Key.StartsWith("System.Net.Http.Response"))
        {
            var cEventStr = JsonConvert.SerializeObject(value.Value);
            var cEvent = JsonConvert.DeserializeAnonymousType(cEventStr, new { Request = new { RequestUri = "" }, Timestamp = 2879029490722 });
            Console.WriteLine($"traceId {activity?.TraceId} Http.Response: {cEvent.Timestamp} ");
        }


        if (value.Key.StartsWith("Microsoft.EntityFrameworkCore.Database.Connection.ConnectionOpening"))
        {
            var cEvent = (Microsoft.EntityFrameworkCore.Diagnostics.ConnectionEventData)value.Value;
            Console.WriteLine($"traceId {activity?.TraceId} Connection.ConnectionOpening: {cEvent?.StartTime.ToString("yyyy-MM-dd HH:mm:ss:fff")} ");
        }
        if (value.Key.StartsWith("Microsoft.EntityFrameworkCore.Database.Command.CommandExecuting"))
        {
            var cEvent = (Microsoft.EntityFrameworkCore.Diagnostics.CommandEventData)value.Value;
            Console.WriteLine($"traceId {activity?.TraceId}  {cEvent?.Command.CommandText} ");
        }
        if (value.Key.StartsWith("Microsoft.EntityFrameworkCore.Database.Connection.ConnectionClosed"))
        {
            var cEvent = (Microsoft.EntityFrameworkCore.Diagnostics.ConnectionEventData)value.Value;
            Console.WriteLine($"traceId {activity?.TraceId} Connection.ConnectionClosed: {cEvent?.StartTime.ToString("yyyy-MM-dd HH:mm:ss:fff")} ");
        }
    }
    public void OnCompleted() { }
    public void OnError(Exception error) { }
}

 

再次启动,查看效果,可以看到已经获取到了http请求的开始结束事件,EF的查询语句,开始事件等。

DiagnosticSource DiagnosticListener 无侵入式分布式跟踪

 

最后我们可以结构化这些数据,并将其持久化到自己的监控体系中,实现链路跟踪。文章来源地址https://www.toymoban.com/news/detail-839708.html

到了这里,关于DiagnosticSource DiagnosticListener 无侵入式分布式跟踪的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 高级分布式系统-第15讲 分布式机器学习--分布式机器学习算法

    高级分布式系统汇总:高级分布式系统目录汇总-CSDN博客 按照通信步调,大致可以分为同步算法和异步算法两大类。 同步算法下,通信过程中有一个显式的全局同步状态,称之为同步屏障。当工作节点运行到 同步屏障 ,就会进入等待状态,直到其工作节点均运行到同步屏障

    2024年01月18日
    浏览(46)
  • 分布式 - 谈谈你对分布式的理解,为什么引入分布式?

    不啰嗦,我们直接开始! 真正了解分布式系统的概念,日后工作中具有分布式系统设计思想。 能否在设计中对系统稳定性方面考虑周全。 能构建高 QPS 健壮的系统架构。 问题分析: 各种分布式框架层出不穷,Spring Cloud,阿里的 Dubbo,无论使用哪一个,原理都相同,考察下基

    2024年02月15日
    浏览(52)
  • 分布式系统面试全集通第一篇(dubbo+redis+zookeeper----分布式+CAP+BASE+分布式事务+分布式锁)

    什么是分布式 一个系统各组件分别部署在不同服务器。彼此通过网络通信和协调的系统。 也可以指多个不同组件分布在网络上互相协作,比如说电商网站 也可以一个组件的多个副本组成集群,互相协作如同一个组件,比如数据存储服务中为了数据不丢失而采取的多个服务备

    2024年04月11日
    浏览(50)
  • 【分布式】分布式共识算法 --- RAFT

    CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance) It states, that though its desirable to have Consistency, High-Availability and Partition-tolerance in every system, unfortunately no system can achieve all three at the same time. 在分布式系

    2024年02月06日
    浏览(51)
  • 分布式爬虫架构-对等分布式(2)

    前言 本文是该专栏的第45篇,后面会持续分享python爬虫干货知识,记得关注。 在面对海量数据的采集需求时,使用分布式爬虫是非常有必要的。继上一篇,详细介绍主从分布式爬虫架构,对主从分布式相关知识感兴趣的同学,可往前翻阅。而本文,笔者再单独来详细介绍分布

    2023年04月25日
    浏览(55)
  • Redis与分布式-分布式锁

    接上文 Redis与分布式-集群搭建 为了解决上述问题,可以利用分布式锁来实现。 重新复制一份redis,配置文件都是刚下载时候的不用更改,然后启动redis服务和redis客户。 redis存在这样的命令:和set命令差不多,但是它有一个机制,当指定的key不存在的时候,才能进行插入,实

    2024年02月07日
    浏览(50)
  • 【分布式】分布式事务:2PC

    分布式事务的问题可以分为两部分: 并发控制 concurrency control 原子提交 atomic commit 分布式事务问题的产生场景:一份数据被分片存在多台服务器上,那么每次事务处理都涉及到了多台机器。 可序列化(并发控制): 定义了事务执行的正确性 真正地并行执行事务,获得真正的

    2024年02月09日
    浏览(46)
  • (快手一面)分布式系统是什么?为什么要分布式系统?分布式环境下会有哪些问题?分布式系统是如何实现事务的?

    《分布式系统原理与泛型》中这么定义分布式系统: “ 分布式系统是若干独立计算机的集合, 这些计算机对于用户来说就像单个相关系统 ”, 分布式系统(distributed system)是建立在网络之上的软件系统。 就比如:用户在使用京东这个分布式系统的时候,会感觉是在使用一

    2024年02月08日
    浏览(70)
  • 分布式系统架构设计之分布式数据存储的扩展方式、主从复制以及分布式一致性

    在分布式系统中,数据存储的扩展是为了适应业务的增长和提高系统的性能。分为水平扩展和垂直扩展两种方式,这两种方式在架构设计和应用场景上有着不同的优势和局限性。 水平扩展是通过增加节点或服务器的数量来扩大整个系统的容量和性能。在数据存储领域,水平扩

    2024年02月03日
    浏览(76)
  • 分布式系统概念和设计——分布式共享内存

    分布式共享内存 分布式共享内存是在不共享物理内存的计算机之间实现数据的共享的一个抽象。 有一个底层运行的系统保证其透明性,但是进程还是根据内存的分布处理物理内存的分布式能力 DMS最关键点: 不需要关心数据的通信,消息传递能力是巨大的底层支持。 生存周

    2024年02月10日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包