.net webapi项目如何集成Exceptionless

这个问题要分大致分为三个阶段:

  • 何为Exceptionelss,为什么要用,用了有什么用,能解决什么问题?
  • 怎样集成到项目中(.NET各种项目),怎样查看记录下来的日志?
  • 可否拦截所有请求,如果可以,怎样做?
  • 其他高阶操作?

以下一一解答这些问题。

what

Exceptionless是一个很好用的日志框架。
所谓框架,是比库(比如类似的NLog,Log4Net等)要大的概念的。
将Exceptionless集成到项目中后,在相应的日志页面就可以看到Exceptionless拦截到的请求的一切(或者几乎一切)内容,比如一个http请求,可以看到它的Request详情、cookie、token、http里面的header、auth,以及Response,耗时,处理请求时的操作系统状态,使用的内存量、如果有异常的话还可以显示堆栈详情……总之,它可以让你在难以调试的环境中保留问题产生时的大量详情,让你可以很容易地重现问题、排查问题以及解决问题。
如下图。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
等等很多详情,更多图就不上了。

设想一下,如果你线上有问题,缺根本没法重现,无规律出现,那该有多么地抓狂。
如果你调试小程序,但小程序的请求不认ip地址,只认域名,那又该如何调试和重现问题。
这些都可以迎刃而解。

how

不是说只能应用在.net项目中,只是我只用在过.net项目中,包括.net framework 和 .net core,当前时间2019.7.20.
方法:

  • 上Exceptionless官网,https://be.exceptionless.io ,注册一个账号,然后在账户的管理中心里配置项目,指明项目是什么类型(如是控制台,是windowsService,是webapi,是webform等等),然后下一页会清楚地告诉你需要添加什么引用,需要在什么地方配置什么内容,非常容易。
    在这里插入图片描述
    然后在此账户的日志页就可以看到了。
    在这里插入图片描述
    然后其实你可能会疑惑,明明发了很多请求啊,为什么这日志里都没有呢?
    原因很简单,因为Exceptionless默认只拦截Exception信息,所以如果一切正常没有Exception被throw出来的话是看不到的。
    当然你也可以自己主动throw一些什么出来,这官网文档里都有。
ex.ToExceptionless.Submit();

这样的。

whether

可否拦截所有请求呢,怎么做?
可以。
自定义一个过滤器,将过滤器添加到每个api接口的Attribute上,即可生效。
思路很简答了,想怎么实现花样就多了。
不罗嗦,直接上我的代码(webapi项目)。

  1. 项目中直接写一个 MiniProFileter.cs文件
    内容:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Exceptionless;
using Exceptionless.Models;
using Exceptionless.Plugins;
using Newtonsoft.Json;
using XueTian.Model;

namespace XueTian.WebApi.Util
{
    /// <summary>
    /// 
    /// </summary>
    public class MiniProFileter : ActionFilterAttribute
    {
        /// <summary>
        /// 自定义过滤器,使用Exceptionless拦截每一个请求
        /// </summary>
        /// <param name="actionContext"></param>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
#if DEBUG

            //base.OnActionExecuting(actionContext);

            //var headerDict = actionContext.Request.Headers.ToDictionary(k => k.Key, v => v.Value);
            //string auth = null;
            //if (headerDict.Keys.Contains("auth"))
            //{
            //    auth = headerDict["auth"].ToList().FirstOrDefault();
            //}
            //DataDictionary dataDict = new DataDictionary() {
            //    { "auth",auth },
            //     { "requestInfo",actionContext.ActionArguments }
            //};

            //var controller = actionContext.ControllerContext.Controller.ToString().Split(new char[] { '.' }).ToList().Last() ?? "--";
            //var source = actionContext.Request.RequestUri.AbsoluteUri.ToString().Split(new char[] { '/' }).ToList().Last() ?? "==";

            //ExceptionlessClient.Default.SubmitEvent(new Event
            //{
            //    Type = controller,
            //    Source = source,
            //    Message = "微信小程序日志--OnActionExecuting",
            //    Data = dataDict
            //});

#endif
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="actionExecutedContext"></param>
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {


            //auth
            var headerDict = actionExecutedContext.Request.Headers.ToDictionary(k => k.Key, v => v.Value);
            string auth = null;
            if (headerDict.Keys.Contains("auth"))
            {
                auth = headerDict["auth"].ToList().FirstOrDefault();
            }
            //host
            string host = null;
            if (headerDict.Keys.Contains("Host"))
            {
                host = headerDict["Host"].ToList().FirstOrDefault();
            }
            //referer
            string referer = null;
            if (headerDict.Keys.Contains("Referer"))
            {
                referer = headerDict["Referer"].ToList().FirstOrDefault();
            }


            //response
            object responseObj = null;
            var resReult = actionExecutedContext.Response.TryGetContentValue(out responseObj);

            DataDictionary dataDict = new DataDictionary() {
                {"auth",auth },
                {"host",host },
                {"request", actionExecutedContext.ActionContext.ActionArguments },
                { "response",resReult ? responseObj : actionExecutedContext.Response.Content}
            };

            //
            var controller = actionExecutedContext.ActionContext.ControllerContext.Controller.ToString().Split(new char[] { '.' }).ToList().Last() ?? "--";
            var source = actionExecutedContext.Request.RequestUri.AbsoluteUri.ToString().Split(new char[] { '/' }).ToList().Last() ?? "==";

            ExceptionlessClient.Default.SubmitEvent(new Event
            {
                Type = source,
                Source = controller,
                Message = actionExecutedContext.Request.GetClientIpAddress(),
                Tags = new TagSet(new[] { actionExecutedContext.Request.Method.ToString(),actionExecutedContext.Request.Headers.Host,actionExecutedContext.Request.Version.ToString(), actionExecutedContext.Request.RequestUri.UserInfo }),
                Date = new DateTimeOffset(DateTime.Now),
                Data = dataDict,
            });


        }
    }
}
  1. 控制器中直接使用,如下图:
    在这里插入图片描述
    至于过滤器究竟是放在控制器的class上,还是具体的方法上,不再多说,稍有经验的都懂。

  2. 最后,日志可见所有请求。
    在这里插入图片描述

Others

其他高阶操作?

默认的免费账户的请求数量是很少的,如何解决呢?
当然最简单是付费,如果不想付费(当然还是建议付费的,毕竟支持一下别人的劳动),那办法就很容易想到,多注册账号,反正换个密钥就能用。

扫描二维码关注公众号,回复: 8707140 查看本文章

另外就是Exceptionless私有化部署,这个我还没试验过,等部署成功了再发出来。


补充

如果要私有化部署,即请求发送到自己的服务器上,如何处理?
方法基本同上,只是指定一下ServerUrl即可,如下示例:

  ExceptionlessClient.Default.Configuration.ServerUrl = "http://exceptionless.mydomain.cn";  //可以写死

            ExceptionlessClient.Default.SubmitEvent(new Event
            {
                Type = KnownTypes.Log,//随便写
                Source = controller + " @ " + DateTime.Now.ToString("MM-dd HH:mm:ss:fff"),//随便写
                Message = actionExecutedContext.Request.GetClientIpAddress(),//随便写
                Tags = new TagSet() { KnownTags.Internal },  //随便写
                Data = dataDict
            });
发布了177 篇原创文章 · 获赞 47 · 访问量 43万+

猜你喜欢

转载自blog.csdn.net/festone000/article/details/96572849