本文主要介绍在请求WebApi时,监控Action执行的时间,及Action传递的参数值,以及Http请求头信息。采用log4net记录监控日志,通过日志记录的时间方便我们定位哪一个Action执行的时间过长,进而采取优化的手段。

监控日志监控的指标如下图

监控程序实现

改监控程序主要继承ActionFilterAttribute类,在命名空间:System.Web.Http.Filters中,重写OnActionExecuted(HttpActionExecutedContext actionExecutedContext) 和OnActionExecuting(HttpActionContext actionContext)两个方法。在上一篇文章介绍MVC的监控也是重写ActionFilterAttribute类,但是MVC的ActionFilterAttribute在System.Web.Mvc命名空间下。

1、监控日志对象
/// <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 == )
{
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(, Parameters.Length - );
}
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;
} }
2、监控程序
[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 = ;
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);
}
} }
3、引用监控

我们可以在每个WebApiController类上或Action上直接引用 [WebApiTracker]即可完成对该WebApiController或Action的监控。

我们也可以在Global.asax中注册全局监控,这样我们就可以监控每一个WebApiController中的Action,代码如下:

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

LoggerHelper 参考下面文章

MVC监控:http://www.cnblogs.com/lc-chenlong/p/4228639.html

WebApi 服务监控的更多相关文章

  1. 学习总结 之 WebApi服务监控 log4net记录监控日志

    在请求WebApi 的时候,我们更想知道在请求数据的时候,调用了哪个接口传了什么参数过来,调用这个Action花了多少时间,有没有人恶意请求.我们可以通过记录日志,对Action进行优化,可以通过日志 ...

  2. Self Host WebApi服务传输层SSL加密(服务器端+客户端调用)

    接上篇<WebApi服务URI加密及验证的两种方式>,在实际开发中,仅对URI进行加密是不够的,在传输层采用SSL加密也是必须的. 如果服务寄宿于IIS,那对传输层加密非常简单仅需要配置一 ...

  3. AJAX跨域调用ASP.NET MVC或者WebAPI服务

    关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案 作者:陈希章 时间:2014-7-3 问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP. ...

  4. 运维架构服务监控Open-Falcon

    一. 介绍 监控系统是整个运维环节,乃至整个产品生命周期中最重要的一环,事前及时预警发现故障,事后提供翔实的数据用于追查定位问题.监控系统作为一个成熟的运维产品,业界有很多开源的实现可供选择.当公司刚 ...

  5. wamp 服务监控和启动

    近日我的 wamp 莫名其妙的崩溃重启,apache 能自动起来, mysql 却悲剧了. 于是有了下面的wamp服务监控和启动的批处理文件 @echo off rem define loop tim ...

  6. SpringCloud系列七:Hystrix 熔断机制(Hystrix基本配置、服务降级、HystrixDashboard服务监控、Turbine聚合监控)

    1.概念:Hystrix 熔断机制 2.具体内容 所谓的熔断机制和日常生活中见到电路保险丝是非常相似的,当出现了问题之后,保险丝会自动烧断,以保护我们的电器, 那么如果换到了程序之中呢? 当现在服务的 ...

  7. C#使用Owin技术部署轻量级webApi服务

    写在前面: 除了使用IIS可以启用WebApi之外,微软还提供了Owin技术,免除了IIS繁琐的部署配置,只需要运行编写好的程序,即可启用webApi服务,是不是很爽呢? 对于Owin技术的详细介绍这 ...

  8. ASP.NET WebApi服务接口如何防止重复请求实现HTTP幂等性

    一.背景描述与课程介绍 明人不说暗话,跟着阿笨一起玩WebApi.在我们平时开发项目中可能会出现下面这些情况; 1).由于用户误操作,多次点击网页表单提交按钮.由于网速等原因造成页面卡顿,用户重复刷新 ...

  9. 如何做自己的服务监控?spring boot 2.x服务监控揭秘

    Actuator是spring boot项目中非常强大一个功能,有助于对应用程序进行监视和管理,通过 restful api请求来监管.审计.收集应用的运行情况,针对微服务而言它是必不可少的一个环节. ...

随机推荐

  1. 无法连接到已配置的开发web服务器

    http://jingyan.baidu.com/article/29697b91099847ab20de3c8b.html 这是防火墙造成的,将防火墙关闭即可

  2. Android_ADB 常用 shell命令 和 sqlite3 简单增删改查

    今天学习了一个ADB的常用命令.接下来简单使用几个常用ADB shell 命令. 首先我们得明白什么是adb.exe ADB -Android Debug Bridge, 是 Android sdk ...

  3. 关于C#不同位数相与或,或赋值时,隐藏位数扩展该留意的问题

    __int64 a; char b; a = b; a |= b; 如上情况,当b的最高位为1时,即b=0x80(或更大)时,b在扩展成64过程中会将最高位向高位扩展变成0xfffffffffffff ...

  4. php 学习使用

    https://netbeans.org/kb/docs/php/wish-list-lesson1_zh_CN.html#register-mysql http://www.php100.com/h ...

  5. java自带BASE64工具进行图片和字符串转换

    java自带BASE64工具进行图片和字符串转换 import java.io.File; import java.io.FileInputStream; import java.io.FileOut ...

  6. linux 下如何安装Telnet ?

    1 如何查看我的linux下是否安装了这个服务?2 没有安装的情况下,如何安装?3 client端 需要安装什么吗? 查看:rpm -qa | grep telnet安装:yum install -y ...

  7. [转] swf文件加密基础

    本来打算下班回来就写这个东西,一方面算是对今天学习的一个笔记记录,另外一方面,给一些朋友普及一些swf文件加密基础知识.之所以说是基础,那是因为我也是刚学习了一点,灰常的基础.不过晚上看了一会我是传奇 ...

  8. Html模板

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5.0 Transitional//EN"> <!-- saved from ur ...

  9. ios开发 通讯录

    一.通信录开发 通信录开发主要是获取用户手机中的联系人 通过获取用户的通信录,可以在应用中添加好友等 二.如何访问用户的通讯录 在iOS9之前,有2个框架可以访问用户的通讯录 目前需要适配iOS8,所 ...

  10. 利用iframe无刷新上传文件的坑

    页面里经常要用到文件上传的功能,而且要求页面不刷新,先说一下原理:页面里放一个file控件和submit按钮,外面用form表单包住,给form表单加上对应的属性值,action.method.ent ...