能够画出Http Request执行时间的波形图:
actionInfo表示MVC中的Action,即按照action类型来分组html
Metric.Context(this.actionInfo.ActionType) .Gauge(counterName, () => milliseconds, Unit.Custom("Milliseconds"));
记录总的请求数和并发请求数:并发
public class WebApiApplication : System.Web.HttpApplication { private readonly Counter totalRequestsCounter = Metric.Context("[Request]").Counter("Total_Requests", Unit.Custom("個"), "request"); private readonly Counter concurrentRequestsCounter = Metric.Context("[Request]").Counter("Concurrent_Requests", Unit.Custom("個"), "request,concurrent"); /// <summary> /// 應用程序啟動方法 /// </summary> protected void Application_Start() { GlobalConfiguration.Configure(WebApiConfig.Register); Metric.Config .WithHttpEndpoint("http://localhost:1234/metrics/"); //Metric.Config.WithHttpEndpoint("http://+:8898/")//外网能够访问 } /// <summary> /// 開始請求 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Application_BeginRequest(object sender, EventArgs e) { totalRequestsCounter.Increment(); concurrentRequestsCounter.Increment(); } /// <summary> /// 結束請求 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Application_EndRequest(object sender, EventArgs e) { concurrentRequestsCounter.Decrement(); } }
度量POST&PUT请求大小的直方图:ide
public PostAndPutRequestSizeMetric(ActionInfo info) : base(info) { this.histogram = Metric.Context(this.actionInfo.ActionType) .Histogram(COUNTER_NAME, Unit.Bytes, SamplingType.FavourRecent); } /// <summary> /// Constant defining the name of this counter /// </summary> public const String COUNTER_NAME = "Post & Put Request Size"; /// <summary> /// Reference to the performance counter /// </summary> private Histogram histogram; public override void OnActionStart() { var method = this.actionInfo.HttpMethod.ToUpper(); if (method == "POST" || method == "PUT") { histogram.Update(this.actionInfo.ContentLength); } }
Histrogram 的度量值不单单是计算最大/小值、平均值,方差,他还展示了分位数(如中位数,或者95th分位数),如75%,90%,98%,99%的数据在哪一个范围内。this
传统上,中位数(或者其余分位数)是在一个完整的数据集中进行计算的,经过对数据的排序,而后取出中间值(或者离结束1%的那个数字,来计算99th分位数)。这种作法是在小数据集,或者是批量计算的系统中,可是在一个高吞吐、低延时的系统中是不合适的。code
一个解决方案就是从数据中进行抽样,保存一个少许、易管理的数据集,而且可以反应整体数据流的统计信息。使咱们可以简单快速的计算给定分位数的近似值。这种技术称做reservoir sampling。orm
Meter度量一系列事件发生的比率:htm
public DeltaExceptionsThrownMetric(ActionInfo info) : base(info) { this.deltaExceptionsThrownCounter = Metric.Context(this.actionInfo.ActionType).Meter(COUNTER_NAME, Unit.Errors, TimeUnit.Seconds); } /// <summary> /// Constant defining the name of this counter /// </summary> public const String COUNTER_NAME = "Errors"; /// <summary> /// Reference to the performance counter /// </summary> private Meter deltaExceptionsThrownCounter; /// <summary> /// Method called by the custom action filter after the action completes /// </summary> /// <remarks> /// If exceptionThrown is true, then the Total Exceptions Thrown counter will be /// incremented by 1 /// </remarks> public override void OnActionComplete(long elapsedTicks, bool exceptionThrown) { if (exceptionThrown) this.deltaExceptionsThrownCounter.Mark(); }
Meter须要除了Name以外的两个额外的信息,事件类型(enent type)跟比率单位(rate unit)。事件类型简单的描述Meter须要度量的事件类型,在上面的例子中,Meter是度量失败的请求数,因此他的事件类型也叫作“Errors”。比率单位是命名这个比率的单位时间,在上面的例子中,这个Meter是度量每秒钟的失败请求次数,因此他的单位就是秒。这两个参数加起来就是表述这个Meter,描述每秒钟的失败请求数。blog
Timer是Histogram跟Meter的一个组合排序
public TimerForEachRequestMetric(ActionInfo info) : base(info) { String controllerName = this.actionInfo.ControllerName; String actionName = this.actionInfo.ActionName; string counterName = string.Format("{0}{1}", controllerName, actionName); this.averageTimeCounter = Metric.Context(this.actionInfo.ActionType) .Timer(counterName, Unit.Requests, SamplingType.FavourRecent, TimeUnit.Seconds, TimeUnit.Milliseconds); } #region Member Variables private Timer averageTimeCounter; #endregion /// <summary> /// Method called by the custom action filter after the action completes /// </summary> /// <remarks> /// This method increments the Average Time per Call counter by the number of ticks /// the action took to complete and the base counter is incremented by 1 (this is /// done in the PerfCounterUtil.IncrementTimer() method). /// </remarks> /// <param name="elapsedTicks">A long of the number of ticks it took to complete the action</param> public override void OnActionComplete(long elapsedTicks, bool exceptionThrown) { averageTimeCounter.Record(elapsedTicks, TimeUnit.Nanoseconds); }