.NET应用程序中的性能监视/度量



我们希望收集有关我们(比如80%的WinApp)应用程序的性能数据,无论是在开发内部还是在客户站点。我们的目标如下:

  • 它应该非常
  • 它应该很轻
  • 它应该允许跟踪/定时&统计我们应用程序中的许多不同类型的事件
  • 它应该能够(有效地)收集相当多的数据,如域、计算机名、用户、操作系统、内存等
  • 收集到的所有数据都应该可以在上述所有维度上进行分析(一旦传输到我们的内部BI数据库)

理想情况下,它也可以在整个站点或逐个用户的基础上进行相对配置以控制:

  • 如果收集到这些性能指标
  • 收集它们有多冗长
  • 是否向我们报告结果

我们一直在计划编写我们自己的系统来完成大部分工作。然后,我们将研究许多不同的"持久性"模型,包括"性能数据包"的二进制格式、XmlSerialization和跟踪日志记录功能,这些功能已经是.NET框架的一部分,仅举几个例子。

不过,在参与这项工作之前,我想仔细检查一下"人群"提出了什么建议。我已经描述了我们正在努力做什么,基本上是我们目前的行动计划,但我正在寻找关于如何最好地解决手头问题的任何和所有建议。

提前谢谢。

看看Metrics.NET,这是一个相对较新的项目,应该可以满足大多数这些需求。它是Java"metrics"项目的一个端口。

(2016年3月添加:)Metrics.NET项目在长时间没有更新后已转移到新用户。

您可以看看在StatsD:之上构建一些东西

https://github.com/etsy/statsd/

有一个.NET包可以在这里找到:

https://github.com/robbihun/NStatsD.Client

它是轻量级的,因为它基本上只是向远程服务器发送UDP数据包。然后,远程服务器将其聚合并存储在Graphite中,Graphite擅长获取这些数据并将其转换为图形,并为您管理数据保留等事务。对于分析,Graphite还允许您将数据输出为JSON(这基本上将您的度量转换为一个double数组),并具有许多功能和过滤器,您可以将其应用于记录的度量,然后将其输入到其他系统中。

有关石墨的一些可能示例,请参见此处:

http://matt.aimonetti.net/posts/2013/06/26/practical-guide-to-graphite-monitoring

然而,它并不能满足您的所有要求,例如能够记录有关客户端的数据,如计算机名称。但你可能可以通过在你的度量名称中使用名称空间来达到这个目标;因此,您将使用类似"client567.orders.loadtime"的键来记录度量,而"client567"将是存储client567在Windows7上使用IE11的其他数据库中的一个条目。

所以这不是一个完全的开箱即用的解决方案,但我认为它形成了一个很好的基础。

另一种选择是使用商业平台,如NewRelic:

http://newrelic.com/

它提供了许多技术的性能监控(从ASP.NET到SQL Server再到Solr)。但是,它确实需要一个在后台运行的代理进程(Windows上的服务)来为您处理监视,这可能是您的选择,也可能不是。它或多或少适用于Web服务器,可能不太适合监视客户端WPF应用程序。

按照你的计划,我会采取这种方法:

  1. 您将把所有性能数据写入日志文件。使用一个快速的C#日志库,如log4net或nlog。如果需要,这些框架支持二进制附加器
  2. 当应用程序开始写入可用的RAM、CPU等时
  3. 使用像PostSharp这样的方面注入器,自动为应用程序中的每个(非内联)方法添加计时器。Stopwatch类不会在性能上产生重大影响。为了使其可配置,让方面注入器根据方法的估计优先级更改日志级别(或者使用您自己的属性来指定)
  4. 在退出(或启动)时提示用户将记录的性能数据发送到您的Web服务器
  5. 在数据传出时对其进行压缩

您可能还想考虑编写自己的锁类。不要使用lock(blah)Monitor.Enter(blah),而是将Monitor.Enter/Exit封装在您自己的一次性类中,该类记录您需要等待多长时间才能进入锁。

我将从测试使用EventLog是否能解决我的问题开始。EventLog消息包含大量信息,您可以添加自己的信息。

对于某些诊断,我会查看(自定义)性能计数器。我敢打赌,很难创建出比windows性能计数器性能更好的东西。

重新写一遍可能不值得。

可能需要在事件查看器中创建特殊的过滤器,以获得您正在寻找的输出,或者跨计算机收集事件(您甚至可以编写自己的查看器)