Hangfire使用ApplicationInsigts监控
起因
我司目前使用清真的ApplicationInsights(以下简称Ai)来做程序级监控。(Ai相关文档: https://azure.microsoft.com/zh-cn/services/application-insights/ )
其实一切都蛮好的,但是我们基于Hangfire的Job系统却无法被Ai所监控到,因为Ai它监控的原理是基于HttpModule对请求进行监控,而Hangfire则是通过轮询Storage(如Sql或者队列)来实现对Job的处理。
也就是说Hangfire理论上是没有任何对Hangfire站点本身的请求,它类似于自己一个while(true)死循环不断地轮询Storage拿到Job任务就执行。
关于Hangfire的系列可以参考官方的说明 http://docs.hangfire.io/en/latest/
虽说Hangfire自己有个Dashboard可以对Hangfire执行的任务进行监控,如下
但是一众的其他站点我全部在Azure的Portal里一目了然,就你一个Hangfire的要我跑到你自己家的Dashboard来看终归不爽,而且也容易忘,导致Hangfire站点常年处于被遗忘的角落。
最近发生了一个Hangfire站点因为某些外部原因没起来(宕掉)的事件之后更加速了要将Hangfire的监控统一到Ai里。
搜索
首先去github上找下有没相关解决方案,老实说觉得基于ai的第三方扩展还是蛮多的,在github搜ai相关的还是能搜索出好几页(https://github.com/topics/application-insights),但并没有找到我需要的。
然后google一下找到有人在hangfire论坛里问跟我类似的问题,然而也没有解决方案(https://discuss.hangfire.io/t/integrating-application-insights-appinsights-into-hangfire/3009)。
既然找不到,那干脆自己撸起袖子干。
开干
首先我们回顾下Ai默认自己监控的原理:
前文说了它有个HttpModule会在请求进来的创建一个RequestTelemetry,
并且会在线程上下文内创建个OperationId,然后在该Request的作用于内所有其他数据(如异常/Http请求/Sql请求)都会跟这个Id关联,
这个Id甚至会在你发送Http请求的时候附加在你的Http Header里,然后接收到该Http请求的站点假如也用了Ai的话会根据这个Header里的Id再进行二次关联(调用链路关联)。
先解决AI需要的相关基础知识
我们要自己在Hangfire里弄AI监控的话,其实重点就是怎么能让Request里的Id能传递到Hangfire里,然后在Hangfire一个操作的作用域里保持该Id一致(串联所有操作)。
那问题重点就清楚了,就是如何解决这个Id的问题。
那Ai自己是如何产生或者获取这个Id的呢,在Ai的2.4版本后引入了对System.Diagnostics.DiagnosticSource这个包的依赖。
所有的Id关联它都基于由此包提供的Activity这个类来事现,详情可以参考 http://apmtips.com/blog/2018/01/23/diagnosticssource-design-principles/
如果需要在自己系统里设置一个Id关联的系统的话也强烈推荐使用Activity这个类来进行处理。
别人实现的比自己弄的科学多了,之前我也自己用AsyncLocal来做过,但是后续也都替换成了Activity,
通过Activity.Current可以获取到当前的Activity实例,通过new Activity然后调用其Start方法也能快速启动一个Activity,
到此Ai相关所需要的知识就都准备妥当了。
然后解决Hangfire需要的相关基础知识
从Hangfire的角度来说,它只要提供2个功能支持就可以了。
在任务入队的时候,在数据里面要塞入在当前Request操作的Id,因为我要将Hangfire的操作能够跟Request里相关联起来。
在任务执行的时候,拿到任务数据的时候,要能取出这个Id,然后将这个Id通过Activity进行Start,然后再任务执行完之后要Stop掉这个Activity并释放掉。
(画的图”有点”丑,但大概就这个意思)
为了解决这个问题查找了下Hangfire全局过滤器相关的资料找到它有IServerFilter和IClientFilter这2个东西:
IServerFilter:服务端处理的过滤器,就是Hangfire Server在执行一个Job的时候要进行处理的过滤器,可在此位置给Hangfire的Job设置Ai的Id到上下文。
IClientFilter:客户端处理的过滤器,就是Hangfire Client在一个Job入队的时候要进行处理的过滤器,可在此位置将Request里的Id赋值给Job Data。
那在Client的时候如何解决每次都能自动塞个Id进去呢?
我的解决思路是定义个JobDtoBase,所有Hangfire任务的数据都要继承自这个类,里面就一个Id,然后通过IClientFilter在每次入队的时候都将当前Activity.Current.Id扔进去
(需要考虑Acitivity.Current为null的情况)
然后如何在Server端自动将这个Id来启动一个Activity并完成监控呢?
我是想着通过IServerFilter里通过PerformingContext里获取Job的参数然后用is来判断如果是JobDtoBase就取它的Id出来然后启动Activity并创建RequestTelemetry。
重点是在Server这边执行结束之后需要将RequestTelemetry和Activity释放掉,所以通过ThreadStatic的静态变量来对其保持引用。
效果
效果如何这个问题暂时我只能呵呵哒,因为也是刚折腾出来还没投入线上运行。
不过从测试环境来看,确实能抓到我hangfire的请求并在Ai里作为Request进行展示:
而且还能抓到依赖项跟”Request”的关联:
所以至少测试的情况来说应该是达到目的了,等之后投入线上后在看下最终具体效果。
Hangfire使用ApplicationInsigts监控的更多相关文章
- 关于hangfire的使用
hangfire 是一个分布式后台执行服务.用它可以代替ThreadPool.QueunItemWork等原生方法.当然4.5后的 task也是相当好用且功能强大.不过如果想分布式处理并且可监控的话, ...
- ABP Framework 5.0 RC.1 新特性和变更说明
.Net 6.0 发布之后,ABP Framework 也在第一时间进行了升级,并在一个多星期后(2021-11-16)发布了 5.0 RC.1 ,新功能和重要变更基本已经确定. 5.0版本新特性 新 ...
- Hangfire项目实践分享
Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 延迟任务执行(De ...
- Hangfire项目实践
Hangfire项目实践分享 Hangfire项目实践分享 目录 Hangfire项目实践分享 目录 什么是Hangfire Hangfire基础 基于队列的任务处理(Fire-and-forget ...
- 关于 hangfire 的权限问题
hangfire 是一个分布式后台执行服务. 官网:http://hangfire.io/ 我看中hangfire的地方是 1:使用简单 2:多种持久化保存方案.支持sqlserver ,msmq等 ...
- [开源] 基于ABP,Hangfire的开源Sharepoint文件同步程序----SuperRocket.SPSync
(一)项目背景 Sharepoint是微软的一个产品,很多公司都在使用它,也有很多公司以前使用它,现在可能需要移植到别的平台,也可能只是移植其中的文件存储,比如说移植到微软云,或者亚马逊云存储.Sup ...
- 【框架学习与探究之定时器--Hangfire】
声明 本文欢迎转载,请注明文章原始出处:http://www.cnblogs.com/DjlNet/p/7603632.html 前言 在上篇文章当中我们知道关于Quartz.NET的一些情况,其实博 ...
- 后台工作者HangFire与ABP框架Abp.Hangfire及扩展
HangFire与Quartz.NET相比主要是HangFire的内置提供集成化的控制台,方便后台查看及监控,对于大家来说,比较方便. HangFire是什么 Hangfire是一个开源框架(.NET ...
- .Net 5分钟搞定网页实时监控
一.为什么会用到网页实时监控 LZ最近在无锡买房了,虽然在上海工作,但是上海房价实在太高无法承受,所以选择还可以接受的无锡作为安身之地.买过房的小伙伴可能知道买房的流程,买房中间有一步很重要的就是需要 ...
随机推荐
- 谷歌chrome 插件(扩展)开发——进阶篇(c#本地程序和插件交互)下
在上一篇中,我提出了总任务.接下来去实现. 获取网页内容等其它信息,这是content.js 擅长做的事情: chrome.extension.onMessage.addListener( funct ...
- wpf 研究之道 winform or wpf,u choose who?
很久以前,我们用winform做过一个五子棋的程序,当时用winform的画图,先画出棋盘...后来项目的研究阶段,偶尔用winform做个小工具.闲暇之余,看到介绍wpf的资料,只知道它采用了xam ...
- python xlsxwriter库生成图表的应用
xlsxwriter可能用过的人并不是很多,不过使用后就会感觉,他的功能让你叹服,除了可以按要求生成你所需要的excel外 还可以加上很形象的各种图,比如柱状图.饼图.折线图等. 请看本人生成的: 这 ...
- 9.python异常处理
常见异常 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x FileNotFoundError 输入/输出异常:基本上是无法打开文件 ImportErro ...
- python 全栈开发,Day1
python基础一 一,Python介绍 python的出生与应用 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中文名字:龟叔)为 ...
- C#将.spl剥离成.emf文件格式
本文转载自 星战紫辉 http://www.cppblog.com/rawdata/archive/2009/02/23/74653.html 但C#代码实现为本人原创.https://github. ...
- EOS 新增的 WebAssembly 解释器,是什么鬼?
Daniel Larimer 在最近的博客中透露,EOS 新增了官方的 WebAssembly 解释器,用来解释执行 WebAssembly 智能合约,加上之前的编译执行,EOS 智能合约有了两种执行 ...
- 笔记:MyBatis XML配置详解
MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息.文档的顶层结构如下: configuration 配置 properties ...
- STL --> map容器
map容器 一.map简介 map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响.对于迭代器来说,可以修改实值,而不能修改key. 二.ma ...
- jQuery中ajax方法无法执行回调函数问题
最近遇到一个问题,发现使用jquery的ajax方法时,回调方法无法执行,而使用$.load()方法时却能正确返回数据.经过长时间调试最终发现是自己粗心大意,原来后台返回的是json数据,而返回的数据 ...