在自定义性能计数器阈值上触发进程转储






4.47/5 (4投票s)
基于自定义性能计数器阈值生成进程转储文件。
引言
我非常喜欢根据您正在调试的场景类型和您面临的约束类型使用正确的工具来生成进程转储。我曾撰文介绍过 ADPlus、DebugDiag 和 ProcDump。这些并不是创建转储文件的唯一工具,还有其他生成进程转储的方法。总的来说,这些工具为应用程序崩溃、挂起、内存问题、性能缓慢等常见问题类别提供了足够的灵活性和选项来生成转储文件。然而,有时需要对触发转储文件生成的事件有更多的灵活性。本文将介绍如何使用性能计数器、Windows 任务计划程序和 ADPlus 来实现这一点。
背景
本文假定您熟悉生产环境调试的基础知识,并且对转储文件有一些基本了解。如果没有,您可以 在此 观看我关于此主题的视频。
性能计数器
性能计数器提供了有关操作系统或任何给定应用程序运行状况的有用信息。这些信息可用于监控应用程序的整体健康状况和可靠性,以及排查性能瓶颈等问题。您还可以创建自定义计数器,并使用它们来跟踪应用程序的健康状况和稳定性。
在本文中,我将演示如何根据这些自定义性能计数器的阈值自动生成转储文件。
创建自定义计数器
有几种创建自定义计数器的方法。涵盖创建这些自定义计数器的所有可能方法超出了本文的范围,但我将仅讨论使用服务器资源管理器创建自定义计数器的步骤。如果您需要了解有关创建自定义计数器的更多信息,可以从 此 文章开始。
使用服务器资源管理器可能是创建自定义性能计数器的最简单方法。只需从 Visual Studio 中启动 **服务器资源管理器**,右键单击 **性能计数器** 节点,然后选择 **创建新类别** 选项,如图 1 所示。
您将看到 **性能计数器生成器** 对话框,您可以在其中输入 **类别** 信息,以及在此类别中添加各个性能计数器,如图 2 所示。
假设我们已经开始在应用程序中使用并发布此计数器。还假设有时在生产环境中 `TransactionsCount` 会变得非常高,而我们无法在内部重现此问题。这种情况显然会使调试和排查此问题变得相当棘手。我们将不得不采用生产环境调试技术,这涉及到仅在问题发生时在生产环境中获取进程转储。挑战当然是如何获取进程转储,因为这个问题只间歇性地发生。这时,我们可以使用性能计数器的数据收集器来触发一个任务,仅当进程达到自定义性能计数器的预定义阈值时才生成进程转储。
下面的代码列表显示了导致 `TransactionsCount` 升高的代码。
private void SimulateHighTransactionsCount()
{
for (int i = 0; i < 100; i++)
{
IncrementTransactionsCount();
System.Threading.Thread.Sleep(1000 * 2);
}
}
private void IncrementTransactionsCount()
{
using (PerformanceCounter TransactionCount = new PerformanceCounter())
{
TransactionCount.CategoryName = "MyApplicationStats";
TransactionCount.CounterName = "TransactionsCount";
TransactionCount.ReadOnly = false;
TransactionCount.Increment();
}
}
一旦上述代码执行,您就可以看到自定义性能计数器升高,如下面的图 3 所示。
设置数据收集器
为了在上述场景中获取进程转储文件,我们将首先使用性能监视器设置一个用户定义的收集器。让我们启动 `PerfMon`,右键单击 **用户定义的收集器集** 选项,然后选择 **新建** -> **收集器集** 选项,如下面的图 4 所示。
此时,您将看到一个对话框,您可以在其中命名您的收集器。请务必选择“**手动创建**”选项。
下一个对话框将提供添加性能计数器的选项。在此处单击“**添加**”按钮。
单击“**添加**”按钮会显示性能计数器列表。从该对话框中选择并添加我们的自定义性能计数器,如下面的图 7 所示。
下一个对话框允许您设置阈值。如图 8 所示,我们希望将 `TransactionsCount` 的阈值设置为 25,以生成转储文件。
在下一个对话框中,只需单击“**保存并关闭**”。
现在,我们需要对这个新创建的收集器做一些调整。因此,单击此收集器的属性,您将看到一个包含三个选项卡的对话框:**警报**、**警报操作** 和 **警报任务**。我们要做的第一件事是在 **警报** 选项卡中调整采样间隔。在本例中,我将其调整为 10 秒,但对于生产环境来说,这可能不是一个合适的值。您可能不想如此频繁地监视计数器,而使用更高的值会更好。
接下来,我们需要在 **警报任务** 选项卡中进行设置。当达到阈值时,我们希望设置要执行的任务的名称。这里使用的名称必须与我们将在下一步使用 Windows 任务计划程序创建任务时使用的名称完全匹配。
Windows 任务计划程序
为了配置每次达到性能计数器阈值时执行的任务,我们将启动 Windows 任务计划程序并创建一个任务。
接下来,我们将设置 **操作**。在我们的例子中,这将是将被执行的命令。
CreateDump.cmd 的内容如下:
CD C:\"Program Files"\"Debugging Tools for Windows"
ADPlus -hang -pn CustomPerformanceCounter.exe -o C:\Test
Logman -stop TransactionsSpike
Pause
我们只是以挂起模式运行 ADPlus。这意味着,一旦 ADPlus 命令运行,它将附加到名为 `CustomPerformanceCounter` 的进程(使用 `-pn` 开关配置)并在 `C:\Test` 文件夹中生成进程转储文件。请注意,我们在 ADPlus 运行后立即停止 `TransactionsSpike` 数据收集器,否则它将继续运行任务,进而继续写入转储文件。考虑到转储文件可能很大的尺寸,您不希望在生产环境中出现这种情况。
我们的设置现在全部完成。我们只需要返回到性能监视器中并启动数据收集器,因为默认情况下,它是以停止模式创建的。现在,一旦您启动数据收集器并且达到阈值,您应该就能看到转储文件。一旦您有了转储文件,您就可以使用任何工具,如 `WinDbg` 或 `DebugDiag` 来分析转储文件并找到问题的根本原因。
摘要
在本文中,我通过结合 ADPlus、性能计数器和 Windows 任务管理器,演示了如何基于自定义性能计数器阈值自动生成进程转储文件。希望您觉得这个技术很有用。
历史
- 2012 年 5 月 13 日:初始版本