咨询热线:15328380324 联系人:辛春艳 地址:台湾省高雄市新興區文橫二路167巷29-1
Net Core集成Exceptionless分布式日志功能以及全局异常过滤
来源:德赢vwin 发布时间:2019-11-10 点击量:153
Net Core集成Exceptionless分布式日志功能以及全局异常过滤
相信很多朋友都看过我的上篇关于Exceptionless的简单入门教程[asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程][https://www.cnblogs.com/yilezhu/p/9193723.html] 上篇文章只是简单的介绍了Exceptionless是什么?能做什么呢?以及怎么进行本地部署和异常提交的简单用法,而这篇文章将带你探讨一下Exceptionless的异常收集高级用法以及你熟悉的类似NLog的日志用法。
这篇文章有一部分内容翻译自官方文档,[点我阅读][https://github.com/exceptionless/Exceptionless.Net/wiki/Sending-Events] 英语好的可以自行阅读 。当然中间很多代码我都进行了重构,还有参考周旭龙的代码,进行了简单地封装,同时加入了为webapi加入异常全局过滤器进行异常日志的记录。希望对大家有所帮助。
本文地址:https://www.cnblogs.com/yilezhu/p/9339017.html作者:依乐祝
手动发送错误
上篇文章介绍了,导入命名空间后,并使用如下代码就可以简单地提交异常日志:
try { throw new ApplicationException(Guid.NewGuid().ToString());} catch (Exception ex) { ex.ToExceptionless().Submit();}
发送附加信息
当然你还可以为发送的事件添加额外的标记信息,比如坐标,标签,以及其他的用户相关的信息等等
try { throw new ApplicationException("Unable to create order from quote.");} catch (Exception ex) { ex.ToExceptionless() // 设置一个ReferenceId方便查找 .SetReferenceId(Guid.NewGuid().ToString("N")) // 添加一个不包含CreditCardNumber属性的对象信息 .AddObject(order, "Order", excludedPropertyNames: new [] { "CreditCardNumber" }, maxDepth: 2) // 设置一个名为"Quote"的编号 .SetProperty("Quote", 123) // 添加一个名为“Order”的标签 .AddTags("Order") // 标记为关键异常 .MarkAsCritical() // 设置一个位置坐标 .SetGeo(43.595089, -88.444602) // 在你的系统中设置userid并提供一个有好的名字,俗称昵称 .SetUserIdentity(user.Id, user.FullName) // 为异常信息添加一些用户描述信息. .SetUserDescription(user.EmailAddress, "I tried creating an order from my saved quote.") // 提交. .Submit();}
统一修改未处理的异常报告
你可以在通过SubmittingEvent 事件设置全局的忽略异常信息添加一些自定义信息等等
#region Exceptionless配置 ExceptionlessClient.Default.Configuration.ApiKey = exceptionlessOptions.Value.ApiKey; ExceptionlessClient.Default.Configuration.ServerUrl = exceptionlessOptions.Value.ServerUrl; ExceptionlessClient.Default.SubmittingEvent += OnSubmittingEvent; app.UseExceptionless();#endregion /// <summary> /// 全局配置Exceptionless /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnSubmittingEvent(object sender, EventSubmittingEventArgs e) { // 只处理未处理的异常 if (!e.IsUnhandledError) return; // 忽略404错误 if (e.Event.IsNotFound()) { e.Cancel = true; return; } // 忽略没有错误体的错误 var error = e.Event.GetError(); if (error == null) return; // 忽略 401 (Unauthorized) 和 请求验证的错误. if (error.Code == "401" || error.Type == "System.Web.HttpRequestValidationException") { e.Cancel = true; return; } // Ignore any exceptions that were not thrown by our code. var handledNamespaces = new List<string> { "Exceptionless" }; if (!error.StackTrace.Select(s => s.DeclaringNamespace).Distinct().Any(ns => handledNamespaces.Any(ns.Contains))) { e.Cancel = true; return; } // 添加附加信息. //e.Event.AddObject(order, "Order", excludedPropertyNames: new[] { "CreditCardNumber" }, maxDepth: 2); e.Event.Tags.Add("MunicipalPublicCenter.BusinessApi"); e.Event.MarkAsCritical(); //e.Event.SetUserIdentity(); }
配合使用 NLog 或 Log4Net
有时候,程序中需要对日志信息做非常详细的记录,比如在开发阶段。这个时候可以配合 log4net 或者 nlog 来联合使用 exceptionless,详细可以查看这个官方的 [示例][https://github.com/exceptionless/Exceptionless.Net/tree/master/samples/Exceptionless.SampleConsole]。
如果你的程序中有在短时间内生成大量日志的情况,比如一分钟产生上千的日志。这个时候你需要使用内存存储(in-memory store)事件,这样客户端就不会将事件系列化的磁盘,所以会快很多。这样就可以使用Log4net 或者 Nlog来将一些事件存储到磁盘,另外 Exceptionless 事件存储到内存当中。
Exceptionless 日志记录的封装
首先简单地封装一个ILoggerHelper接口
/// <summary> /// lzhu /// 2018.7.19 /// 日志接口 /// </summary> public interface ILoggerHelper { /// <summary> /// 记录trace日志 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> void Trace(string source, string message, params string[] args); /// <summary> /// 记录debug信息 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> void Debug(string source, string message, params string[] args); /// <summary> /// 记录信息 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> void Info(string source, string message, params string[] args); /// <summary> /// 记录警告日志 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> void Warn(string source, string message, params string[] args); /// <summary> /// 记录错误日志 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> void Error(string source, string message, params string[] args); }
既然有了接口,那么当然得实现它了
/// <summary> /// lzhu /// 2018.7.19 /// Exceptionless日志实现 /// </summary> public class ExceptionlessLogger : ILoggerHelper { /// <summary> /// 记录trace日志 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">添加标记</param> public void Trace(string source,string message, params string[] args) { if (args != null && args.Length > 0) { ExceptionlessClient.Default.CreateLog(source, message, LogLevel.Trace).AddTags(args).Submit(); } else { ExceptionlessClient.Default.SubmitLog(source, message, LogLevel.Trace); } } /// <summary> /// 记录debug信息 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> public void Debug(string source, string message, params string[] args) { if (args != null && args.Length > 0) { ExceptionlessClient.Default.CreateLog(source, message, LogLevel.Debug).AddTags(args).Submit(); } else { ExceptionlessClient.Default.SubmitLog(source, message, LogLevel.Debug); } } /// <summary> /// 记录信息 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> public void Info(string source, string message, params string[] args) { if (args != null && args.Length > 0) { ExceptionlessClient.Default.CreateLog(source, message, LogLevel.Info).AddTags(args).Submit(); } else { ExceptionlessClient.Default.SubmitLog(source, message, LogLevel.Info); } } /// <summary> /// 记录警告日志 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> public void Warn(string source, string message, params string[] args) { if (args != null && args.Length > 0) { ExceptionlessClient.Default.CreateLog(source, message, LogLevel.Warn).AddTags(args).Submit(); } else { ExceptionlessClient.Default.SubmitLog(source, message, LogLevel.Warn); } } /// <summary> /// 记录错误日志 /// </summary> /// <param name="source">信息来源</param> /// <param name="message">日志内容</param> /// <param name="args">标记</param> public void Error(string source, string message, params string[] args) { if (args != null && args.Length > 0) { ExceptionlessClient.Default.CreateLog(source, message, LogLevel.Error).AddTags(args).Submit(); } else { ExceptionlessClient.Default.SubmitLog(source, message, LogLevel.Error); } } }
当然实现好了,可别忘了依赖注入哦
//注入ExceptionlessLogger服务 services.AddSingleton<ILoggerHelper, ExceptionlessLogger>();
这时候该写一个全局异常过滤器了
/// <summary> /// lzhu /// 2018.7.19 /// 定义全局过滤器 /// </summary> public class GlobalExceptionFilter : IExceptionFilter { private readonly ILoggerHelper _loggerHelper; //构造函数注入ILoggerHelper public GlobalExceptionFilter(ILoggerHelper loggerHelper) { _loggerHelper = loggerHelper; } public void OnException(ExceptionContext filterContext) { _loggerHelper.Error(filterContext.Exception.TargetSite.GetType().FullName, filterContext.Exception.ToString(), MpcKeys.GlobalExceptionCommonTags, filterContext.Exception.GetType().FullName); var result = new BaseResult() { errcode = ResultCodeAddMsgKeys.CommonExceptionCode,//系统异常代码 errmsg= ResultCodeAddMsgKeys.CommonExceptionMsg,//系统异常信息 }; filterContext.Result = new ObjectResult(result); filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; filterContext.ExceptionHandled = true; } }
全局过滤器写好了,怎么让它生效呢,客观别急啊,上正菜
//添加验证 services.AddMvc(options=> { options.Filters.Add<GlobalExceptionFilter>(); }).AddFluentValidation();
哈哈,没什么说的了,代码都已经写好了,剩下的就是上代码测试结果了。我这里只是简单地api测试下,万能的ValuesController登场:
// GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { //try //{ throw new Exception($"测试抛出的异常{id}"); //} //catch (Exception ex) //{ // ex.ToExceptionless().Submit(); //} //return "Unknown Error!"; }
这里是直接抛出异常,不进行trycatch,这时候异常会被全局过滤器捕获,然后放到Exceptionless的Log里面,别问我为什么会在log里面,因为我全局过滤器代码里面已经写明了,不明白的回去看代码,然后看接口调用的实现方法。下面上结果:
点进去,看看详细信息:
再测试下使用try catch捕获的异常处理,这时候异常信息会被提交到Exception这个里面。直接上代码吧
// GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { try { throw new Exception($"测试抛出的异常{id}"); } catch (Exception ex) { ex.ToExceptionless().Submit(); } return "Unknown Error!"; }
到exceptionless里面看看不活的异常吧。打字很累直接上图吧
点进去看看详细信息,有三个tab,下面之粘贴一个图片了:
最后,源码就不上了,因为上面代码很清楚了
总结
本文没有对Exceptionless进行过多地介绍,因为博主的[上篇文章][https://www.cnblogs.com/yilezhu/p/9193723.html] 已经进行了详细的介绍。直接切入正题,先对官方高级用法进行了简单地翻译。然后对Exceptionless Log这个eventtype进行了简单地封装,让你可以像使用NLog一样很爽的使用Exceptionless。最后通过一个asp.net core web api的项目进行了演示,在全局过滤器中利用封装的Log方法进行全局异常的捕获。希望对大家使用Exceptionless有所帮助。
相关产品
-
城市作为一种全域旅游综合载体,包含了食、住、行、游、购、娱等所有元素,在目的地营销中的重要性不言而喻。《魅力中国城》总导演史帆介绍,《魅力中国城》以全局视角展现城市的旅游风采,从地理、人文、产业多角度,审视城市旅游,构建起一个以城市为中心的复合型平台,推动了产业、科技、金融融合发展的良性格局。
-
范冰冰:不是特意的。交了一个健身的男友,总是也要有收益的嘛。我没有刻意瘦。他健身,我就跟他边上做些运动。我原来是完全没有运动的,可能有些变化吧。(从认识李晨到现在)差不多瘦了15斤吧。
-
中新网11月23日电 据《欧洲时报》报道,法国国家统计及经济研究所(统经所)在最新版“法国社会肖像”中,探讨了法国“收入中位数”的家庭,这类人群目前约有1160万,增速超过其它所有阶层。
-
为了让车子寿命更长,建议无论新车或旧车都应做底盘的防锈处理,即时下流行的底盘装甲。底盘装甲是在车底喷涂一层5毫米左右的高分子橡胶聚合物,凝固后就如装甲一般护住底盘,不易干裂、脱落,具有防沙石撞击、耐酸雨、防腐蚀等优点。此外,底盘装甲还能减震隔音,提高舒适性。要知道,汽车噪音很大一部分来自于路噪和沙石敲击的声音,底盘装甲的高弹性能可有效吸收和降低这些噪音,同时也减少由于底盘钢板震动而引起的噪音,达到降噪作用,提高车辆行驶时的舒适性。
-
据了解,几位长期关注比特币的美国金融专家一致认为,就像前十年来的黄金一样,比特币不过是另一个泡沫而已,是一个最坏的冒险机会。比特币的火热也和金价曾经的高涨一样,恰恰从另一方面体现了欧美的金融状况有多么的糟糕、现金持有人有多么的恐慌。
-
频打呵欠?血压异常?头晕?流鼻血...注意啦!“健康榜”提醒您,这是身体发送发生血栓的6个信号,赶紧凑过来听听“健康榜”怎么说吧。
-
谁能在未来成为“北京王朝”的有力挑战者?半决赛输给北京队后,曾经创立了“宏远王朝”的广东队已在近三次季后赛交手中全部败在北京队手下,拜纳姆与易建联配合的日趋成熟以及朱芳雨的老树开花让人对他们重回巅峰产生过无限遐想,但结果还是证明,目前的北京队依然是两者间更好的那支球队。
-
一、王菲李亚鹏从泡夜店的喜爱程度上说,王菲与李亚鹏可以说是“天造地设”的一对,曾经妇唱夫随。记者第一次撞破王菲李亚鹏恋情就是在当时郑钧开的酒吧,当时是2005年夏天。两人结婚之初,经常呼朋唤友,到夜店聚会。每当他们夫妇光临,夜店都防范严密,有一次夜店保安发现门前有狗仔,不仅通风报信,还安排“鹏菲”从后门撤离。当保安们看到狗仔偷拍未成,追车不及,竟传出一片笑声,这样的“正义感”记者曾体验过多次。
热点资讯
- 紫天科技任性“买!买!买!”的玄机2019-06-23
- 19岁男子偷157枚比特币,买迈凯伦后被捕2019-06-23
- 泉城义工向全体市民发出倡议:积极行动起来为文明城市增光添彩2019-10-30
- 农民专业合作社带活新疆农村经济2019-10-29
- 微软最新分析报告:印度91%新PC电脑均安装盗版软件2019-06-23
- 重磅|长生疫苗案问责名单!吉林副省长被免职!2019-06-23
- 1-2【包子mysql系列】,对mysql的innoDB加锁分析2019-11-05
- 苹果谷歌亚马逊等科技股全线下跌:市值蒸发827亿美元2019-11-06