WebApi 服务监控
本文主要介绍在请求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 服务监控的更多相关文章
- 学习总结 之 WebApi服务监控 log4net记录监控日志
在请求WebApi 的时候,我们更想知道在请求数据的时候,调用了哪个接口传了什么参数过来,调用这个Action花了多少时间,有没有人恶意请求.我们可以通过记录日志,对Action进行优化,可以通过日志 ...
- Self Host WebApi服务传输层SSL加密(服务器端+客户端调用)
接上篇<WebApi服务URI加密及验证的两种方式>,在实际开发中,仅对URI进行加密是不够的,在传输层采用SSL加密也是必须的. 如果服务寄宿于IIS,那对传输层加密非常简单仅需要配置一 ...
- AJAX跨域调用ASP.NET MVC或者WebAPI服务
关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案 作者:陈希章 时间:2014-7-3 问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP. ...
- 运维架构服务监控Open-Falcon
一. 介绍 监控系统是整个运维环节,乃至整个产品生命周期中最重要的一环,事前及时预警发现故障,事后提供翔实的数据用于追查定位问题.监控系统作为一个成熟的运维产品,业界有很多开源的实现可供选择.当公司刚 ...
- wamp 服务监控和启动
近日我的 wamp 莫名其妙的崩溃重启,apache 能自动起来, mysql 却悲剧了. 于是有了下面的wamp服务监控和启动的批处理文件 @echo off rem define loop tim ...
- SpringCloud系列七:Hystrix 熔断机制(Hystrix基本配置、服务降级、HystrixDashboard服务监控、Turbine聚合监控)
1.概念:Hystrix 熔断机制 2.具体内容 所谓的熔断机制和日常生活中见到电路保险丝是非常相似的,当出现了问题之后,保险丝会自动烧断,以保护我们的电器, 那么如果换到了程序之中呢? 当现在服务的 ...
- C#使用Owin技术部署轻量级webApi服务
写在前面: 除了使用IIS可以启用WebApi之外,微软还提供了Owin技术,免除了IIS繁琐的部署配置,只需要运行编写好的程序,即可启用webApi服务,是不是很爽呢? 对于Owin技术的详细介绍这 ...
- ASP.NET WebApi服务接口如何防止重复请求实现HTTP幂等性
一.背景描述与课程介绍 明人不说暗话,跟着阿笨一起玩WebApi.在我们平时开发项目中可能会出现下面这些情况; 1).由于用户误操作,多次点击网页表单提交按钮.由于网速等原因造成页面卡顿,用户重复刷新 ...
- 如何做自己的服务监控?spring boot 2.x服务监控揭秘
Actuator是spring boot项目中非常强大一个功能,有助于对应用程序进行监视和管理,通过 restful api请求来监管.审计.收集应用的运行情况,针对微服务而言它是必不可少的一个环节. ...
随机推荐
- Redis运维的一些常用的命令总结
最近一直管理部门的一些redis的服务器,所以现在来总结一下redis的一些常用的运维命令: 1.time 显示服务器的时间,时间戳(秒) 微秒数 redis 127.0.0.1:6380> ...
- Android,配置Activity为启动Activity(AndroidManifest.xml,application,intent-filter,MAIN,LAUNCHER)
备忘: 将Activity注册为启动Activity. 在AndroidManifest.xml中的<application>元素中加入以下<activity>子元素内容: & ...
- eclipse颜色 字体
字体 之前也想过搜个字体,但是看了别人的推荐也没什么太大感觉.今天我自己选择了一款字体,发现看着单词中的i等瘦型的字母会比较费力,现在我知道自己想要什么样的字体了.网上推荐Inconsolata.pf ...
- 【原】JS原型的动态性及实例与原型的关系
今天再读了<JS高程>的第六章,有了些深入的感悟和理解,总结分享一下. 创建对象的方式有很多,有一种是动态原型模式,最实用的是构造函数与原型组合的模式,原型的动态性在这两个模式里都有所体现 ...
- oracle 客户端重新安装遇到的问题
前一阵,因为把ORACLE客户端的密码忘记了,在网上也找了好多方法,试着不重新安装找回密码,可是都行不通,没有办法重新装.安装时遇到一些问题,因为我是WIN7,64位系统,安装的oracle11g64 ...
- bs4的学习
soup = BeautifulSoup(html,'html.parser') #'html.parser'是html解析器必须有soup.find_all("a") #等价于 ...
- Elasticsearch 插件安装
http://www.cnblogs.com/richaaaard/p/5212044.html
- 把表里的数据转换为insert 语句
当表里面有数据时,怎么把表里的数据转换为insert 语句 (从别人那里看来的用SQLServer 2008 R2测试可用) CREATE PROC spGenInsertSQL @TableName ...
- xUtils框架的使用
xUtils简介 xUtils 包含了很多实用的android工具,xUtils 源于Afinal框架,对Afinal进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持,拥有 ...
- ssh框架整合---- spring 4.0 + struts 2.3.16 + maven ss整合超简单实例
一 . 需求 学了这么久的ssh,一直都是别人整合好的框架去写代码,自己实际动手时才发现框架配置真是很坑爹,一不小心就踏错,真是纸上得来终觉浅! 本文将记录整合struts + spring的过程 , ...