WebApi 服務監控

本文主要介紹在請求WebApi時,監控Action執行的時間,及Action傳遞的參數值,以及Http請求頭信息。採用log4net記錄監控日誌,經過日誌記錄的時間方便咱們定位哪個Action執行的時間過長,進而採起優化的手段。html

監控日誌監控的指標以下圖

監控程序實現

改監控程序主要繼承ActionFilterAttribute類,在命名空間:System.Web.Http.Filters中,重寫OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 和OnActionExecuting(HttpActionContext actionContext)兩個方法。在上一篇文章介紹MVC的監控也是重寫ActionFilterAttribute類,可是MVC的ActionFilterAttribute在System.Web.Mvc命名空間下ide

一、監控日誌對象
/// <summary>
    /// 監控日誌對象
    /// </summary>
    public class WebApiMonitorLog
    {
        public string ControllerName
        {
            get;
            set;
        }
        public string ActionName
        {
            get;
            set;
        }

        public DateTime ExecuteStartTime
        {
            get;
            set;
        }
        public DateTime ExecuteEndTime
        {
            get;
            set;
        }
        /// <summary>
        /// 請求的Action 參數
        /// </summary>
        public Dictionary<string, object> ActionParams
        {
            get;
            set;
        }
        /// <summary>
        /// Http請求頭
        /// </summary>
        public string HttpRequestHeaders
        {
            get;
            set;
        }

        /// <summary>
        /// 請求方式
        /// </summary>
        public string HttpMethod
        {
            get;
            set;
        }
        /// <summary>
        /// 請求的IP地址
        /// </summary>
        public string IP
        {
            get;
            set;
        }

        /// <summary>
        /// 獲取監控指標日誌
        /// </summary>
        /// <param name="mtype"></param>
        /// <returns></returns>
        public string GetLoginfo()
        {
            string Msg = @"
            Action執行時間監控:
            ControllerName:{0}Controller
            ActionName:{1}
            開始時間:{2}
            結束時間:{3}
            總 時 間:{4}秒
            Action參數:{5}
            Http請求頭:{6}
            客戶端IP:{7},
            HttpMethod:{8}
                    ";
            return string.Format(Msg,
                ControllerName,
                ActionName,
                ExecuteStartTime,
                ExecuteEndTime,
                (ExecuteEndTime - ExecuteStartTime).TotalSeconds,
                GetCollections(ActionParams),
                 HttpRequestHeaders,
                IP,
                HttpMethod);
        }

        /// <summary>
        /// 獲取Action 參數
        /// </summary>
        /// <param name="Collections"></param>
        /// <returns></returns>
        public string GetCollections(Dictionary<string, object> Collections)
        {
            string Parameters = string.Empty;
            if (Collections == null || Collections.Count == 0)
            {
                return Parameters;
            }
            foreach (string key in Collections.Keys)
            {
                Parameters += string.Format("{0}={1}&", key, Collections[key]);
            }
            if (!string.IsNullOrWhiteSpace(Parameters) && Parameters.EndsWith("&"))
            {
                Parameters = Parameters.Substring(0, Parameters.Length - 1);
            }
            return Parameters;
        }

        /// <summary>
        /// 獲取IP
        /// </summary>
        /// <returns></returns>
        public string GetIP()
        {
            string ip = string.Empty;
            if (!string.IsNullOrEmpty(System.Web.HttpContext.Current.Request.ServerVariables["HTTP_VIA"]))
                ip = Convert.ToString(System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]);
            if (string.IsNullOrEmpty(ip))
                ip = Convert.ToString(System.Web.HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]);
            return ip;
        }


    }
二、監控程序
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
    public class WebApiTrackerAttribute : ActionFilterAttribute//, ExceptionFilterAttribute  
    {
        private readonly string Key = "_thisWebApiOnActionMonitorLog_";
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            base.OnActionExecuting(actionContext);
            WebApiMonitorLog MonLog = new WebApiMonitorLog();
            MonLog.ExecuteStartTime = DateTime.Now;
            //獲取Action 參數
            MonLog.ActionParams = actionContext.ActionArguments;
            MonLog.HttpRequestHeaders = actionContext.Request.Headers.ToString();
            MonLog.HttpMethod = actionContext.Request.Method.Method;
           
            actionContext.Request.Properties[Key] = MonLog;
            var form=System.Web.HttpContext.Current.Request.Form;
            #region 若是參數是實體對象,獲取序列化後的數據
            Stream stream = actionContext.Request.Content.ReadAsStreamAsync().Result;
            Encoding encoding = Encoding.UTF8;
            stream.Position = 0;
            string responseData = "";
            using (StreamReader reader = new StreamReader(stream, encoding))
            {
                responseData = reader.ReadToEnd().ToString();
            }
            if (!string.IsNullOrWhiteSpace(responseData) && !MonLog.ActionParams.ContainsKey("__EntityParamsList__"))
            {
                MonLog.ActionParams["__EntityParamsList__"] = responseData;
            }
            #endregion
        }

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            WebApiMonitorLog MonLog = actionExecutedContext.Request.Properties[Key] as WebApiMonitorLog;
            MonLog.ExecuteEndTime = DateTime.Now;
            MonLog.ActionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
            MonLog.ControllerName = actionExecutedContext.ActionContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            Log.Info(MonLog.GetLoginfo());
            if (actionExecutedContext.Exception != null)
            {
                string Msg = string.Format(@"
                請求【{0}Controller】的【{1}】產生異常:
                Action參數:{2}
               Http請求頭:{3}
                客戶端IP:{4},
                HttpMethod:{5}
                    ", MonLog.ControllerName, MonLog.ActionName, MonLog.GetCollections(MonLog.ActionParams), MonLog.HttpRequestHeaders, MonLog.GetIP(), MonLog.HttpMethod);
                Log.Error(Msg, actionExecutedContext.Exception);
            }
        }

    }
三、引用監控

咱們能夠在每一個WebApiController類上或Action上直接引用 [WebApiTracker]便可完成對該WebApiController或Action的監控。優化

咱們也能夠在Global.asax中註冊全局監控,這樣咱們就能夠監控每個WebApiController中的Action,代碼以下:this

 protected void Application_Start()
        {
            
            GlobalConfiguration.Configuration.Filters.Add(new WebApiTrackerAttribute());
            AreaRegistration.RegisterAllAreas();
        }

LoggerHelper 參考下面文章

MVC監控:http://www.cnblogs.com/lc-chenlong/p/4228639.htmlspa

相關文章
相關標籤/搜索