跟踪数据访问
注意:本文的更新版本适用于 SQL Server 2008,请参阅 https://msdn.microsoft.com/en-us/library/cc765421.aspx。
注意:本文的更新版本适用于 SQL Server 2005,请参阅 https://msdn.microsoft.com/en-us/library/aa964124(SQL.90).aspx。
Bob Beauchemin
DevelopMentor
2004 年 11 月
适用于:
Microsoft ADO.NET 2.0
Microsoft .NET Framework 2.0
Microsoft SQL Server
总结: 了解如何应用 ADO.NET 2.0 中的跟踪功能来跟踪应用程序中的 bug 和瓶颈。 ) (13 个打印页
下载关联的 2005TracingExamples.exe 代码示例。
目录
简介
设置数据跟踪
运行跟踪
读取跟踪输出
配置跟踪的应用程序
使用跟踪调试参数绑定问题
两个关键诊断方案
内部数据跟踪
结论
简介
自 ODBC 跟踪以来,我一直缺少用于数据访问的良好通用内置跟踪工具。 OLE DB 具有许多不同类型的跟踪;想到的两个是 Visual Studio 分析器兼容的检测和 ATLTRACE (ATL OLE DB 模板的跟踪宏) 。 OLE DB 和 MDAC 的问题不在于没有跟踪,而是存在太多单独的跟踪类型,每种跟踪都与不同的评估机制相关联。 很难(如果不是不可能)向下追溯到数据访问堆栈的各个层并获取一个跟踪输出。
ADO.NET 2.0 和 SQL Native Client (新的 OLE DB/ODBC/网络库功能,) 包含灵活、丰富的内置数据跟踪工具。 Microsoft 已检测其所有四个 .NET 数据提供程序, (SqlClient、OracleClient、OleDb 桥和 Odbc 桥) 、ADO.NET DataSet 和友元、SQL Native 客户端 OLE DB 和 ODBC 提供程序/驱动程序,以及SQL Server 2005 网络库。 本文中的信息旨在帮助你快速启动和跟踪,展示如何执行一些粗略的跟踪文件分析,并查看简单的跟踪用例。 在本文末尾,我将讨论如何构建跟踪层,以便可扩展到不同的跟踪技术,并建议更多使用它的方法。
跟踪点已编程到 .NET 和 SQL 本机客户端库。 使用反射器等 IL 反汇编程序时,你可能已经注意到了它们。 第一步是配置一些内容,以便获取基本输出。
使用跟踪的基本步骤包括:
- 设置数据跟踪 DLL 注册表项、ETW 提供程序和 WMI 架构。
- 配置并运行跟踪本身。
- 以逗号分隔的值文件的形式获取跟踪结果。
如果某些首字母缩略词(如 ETW 和 WMI)目前不熟悉,请不要担心。 让我们逐一了解这些步骤,然后回到讨论它们的工作原理。
注意 如果要在开始设置数据跟踪之前了解其工作原理,请阅读本文末尾处显示的“内部数据跟踪”。
设置数据跟踪
设置跟踪 DLL 注册表项: 此步骤包括运行注册表脚本或手动编辑注册表,以将数据跟踪连接到其 Windows (ETW) 提供程序的事件跟踪。 目前,编辑注册表是实现此目的的唯一方法;将来可能会有控制面板应用程序或配置文件机制。 我们稍后将详细介绍如何使用此注册表项。现在,让我们在计算机上为每个与数据相关的进程启用跟踪。
- 找到注册表项 HKLM\Software\Microsoft\BidInterface\Loader。
- 在 Loader 键) 下添加新的字符串值 (:
Name=“:P ath” Value=“C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607\AdoNetDiag.dll”
这假定你已安装 .NET Framework 2.0 的 Beta 1 版本,并且系统驱动器为 C:\驱动。 请注意, Path 之前的冒号很重要。 还可以运行本文随附的 setup_trace.reg 文件。
注册数据跟踪架构: 刚刚注册的AdoNetDiag.dll是一个适配器组件,它使任何针对数据跟踪进行检测的库都类似于 Windows 提供程序的事件跟踪。 现在可以使用提供程序,但要使其显示在公共提供程序列表和 WMI 工具中,你需要为AdoNetDiag.dll公开的事件注册 ETW 提供程序及其 WMI 架构。 可以使用名为 MOF 文件的特殊格式架构文件和名为 mofcomp 的实用工具执行此操作。 ADO.NET 2.0 在 C:\WINDOWS\Microsoft.NET\Framework\v2.0.40607 目录中提供 MOF 文件,但是,由于数据跟踪是正在进行的工作,因此为了获得最佳结果,应使用本文附带的 MOF 文件。 运行本文附带的 Windows register_mof.cmd 脚本;它运行注册代码。 如果从命令行手动发出命令,它将如下所示。
mofcomp adonetdiag_beta1.mof
可以通过使用 命令列出 ETW 提供程序来检查提供程序是否正确注册
1> logman query providers
应会看到已注册的提供商,以及 OS 或其他产品附带的其他提供商。 请注意,每个提供程序都由 GUID 标识。 提供程序列表应如下所示:
Provider GUID
--------------------------------------------------------------------------
*System.Data.1 {914ABDE2-171E-C600-3348-C514171DE148}
ACPI Driver Trace Provider {dab01d4d-2d48-477d-b1c3-daad0ce6f06b}
Active Directory: Kerberos {bba3add2-c229-4cdb-ae2b-57eb6966b0c4}
IIS: SSL Filter {1fbecc45-c060-4e7c-8a0e-0dbd6116181b}
IIS: WWW Server {3a2a4e84-4c21-4981-ae10-3fda0d9b0f83}
IIS: Active Server Pages (ASP) {06b94d9a-b15e-456e-a4ef-37c984a2cb4b}
MSSQLSERVER Trace {2373A92B-1C1C-4E71-B494-5CA97F96AA19}
Local Security Authority (LSA) {cc85922f-db41-11d2-9244-006008269001}
*System.Data.SNI.B1 {C22CFA1B-A312-354C-33F7-ACACA46CE990}
*SQLNCLI.1 {BA798F36-2325-EC5B-ECF8-76958A2AF9B5}
Windows Kernel Trace {9e814aad-3204-11d2-9a82-006008a86939}
*System.Data.OracleClient.1 {DCD90923-4953-20C2-8708-01976FB15287}
*ADONETDIAG.ETW {8B98D3F2-3CC6-0B9C-6651-9649CCE5C752}
ASP.NET Events {AFF081FE-0247-4275-9C4E-021F3DC1DA35}
NTLM Security Protocol {C92CF544-91B3-4dc0-8E11-C580339A0BF8}
IIS: WWW Isapi Extension {a1c2040e-8840-4c31-ba11-9871031a19ea}
HTTP Service Trace {dd5ef90a-6398-47a4-ad34-4dcecdef795f}
Spooler Trace Control {94a984ef-f525-4bf1-be3c-ef374056a592}
我稍微更改了输出,在我们关注的提供程序旁边添加了一个星号。 还可以检查使用 WMI CIM Studio 工具注册的 WMI 架构。 可以下载 WMI 管理工具。 用于数据跟踪的 WMI 架构非常简单,我们稍后将讨论它们。
运行跟踪
运行跟踪包括定义命名跟踪并发出 ETW 命令,以使用名为 logman 的实用工具 (日志管理器) 使用它们。 通过运行本文随附的脚本 traceon.cmd 来启动跟踪。 假设你运行的是 Windows 2003,则 文件中的 命令如下所示:
@Logman start MyTrace -pf ctrl.guid.adonet.beta1 -ct perf -o Out.etl -ets
此命令文件定义单个命名跟踪实例 (MyTrace) 指定我们刚刚注册的所有提供程序。 提供程序的列表和提供程序选项在单独的文件 ctrl.guid.adonet.beta1 中指定。 此文件的内容包括:
{7ACDCAC8-8947-F88A-E51A-24018F5129EF} 0x00000000 0 ADONETDIAG.ETW
{914ABDE2-171E-C600-3348-C514171DE148} 0x00000000 0 System.Data.1
{C22CFA1B-A312-354C-33F7-ACACA46CE990} 0x00000000 0 System.Data.SNI.B1
{DCD90923-4953-20C2-8708-01976FB15287} 0x00000000 0 System.Data.OracleClient.1
{BA798F36-2325-EC5B-ECF8-76958A2AF9B5} 0x00000000 0 SQLNCLI.1
这些行包括每个提供程序的 GUID、提供程序选项以及换行) (watch提供程序的名称。 稍后我们将详细介绍提供程序选项。
以这种方式调用 logman 会将简洁的二进制格式的所有事件写入事件跟踪日志文件。 根据约定,这些文件的后缀为 .etl。 打开它后,请运行示例程序,GetDataSet.exe,随本文的下载内容一起提供。 通过运行脚本 traceoff.cmd 关闭跟踪。 这只会发出 命令:
@Logman stop MyTrace -ets
应该会在发出命令的目录中看到一个名为“out.etl”的大约 150KB 文件。 由于我们已在每个详细信息级别上打开跟踪提供程序, (ADO.NET 提供程序、网络调用和来自SQL Server的响应(如果它在同一台计算机) 上运行),因此将有大量的输出。 稍后我们将探讨筛选输出的方法。 请注意,启动 Visual Studio 2005 来运行测试程序可能会生成额外的跟踪事件,例如,当服务器资源管理器运行数据访问代码时。
以 CSV 文件的形式获取结果:
out.etl 文件不是人类可读格式,除非你是喜欢读取二进制文件的少数人之一。 ETW 实用工具包括一个名为 tracerpt.exe 的基本格式化程序,用于将其转换为逗号分隔值文件。 若要获取 CSV 文件,请运行 report.cmd,这会发出以下命令:
@TraceRPT /y Out.etl
此实用工具生成两个文件:summary.txt、会话中捕获的跟踪事件的摘要和dumpfile.csv。 这些是 tracerpt 输出的默认文件名,可以通过命令行选项更改它们。 Dumpfile.csv是包含所需信息的文件。 目前可以使用 Excel 浏览此文件;稍后,可以执行一些进一步的后处理,例如将数据加载到SQL Server并使用 SQL 进行查询。 就是这么简单! 现在有了第一个跟踪。 让我们看一下输出。
读取跟踪输出
数据跟踪提供程序公开三种主要类型的信息:跟踪点信息和提供程序标识、事件类型以及线程和计时信息。 具体而言,信息列包括:
事件名称 - 数据跟踪事件提供程序的名称
事件类型 - TextW 或 TextA
TID - 线程 ID
时钟时间 - 事件的时间戳
内核 (毫秒) — 内核模式下的毫秒数 (CPU 时间)
用户 (毫秒) — 用户模式下的毫秒数 (CPU 时间)
用户数据 - 有关跟踪点的详细信息
尽管允许 WMI 提供程序公开复杂架构,但数据跟踪提供程序只公开两种简单的事件类型:TextW 和 TextA。 TextW 用于 Unicode 字符消息,TextA 用于 ANSI 字符消息。 请注意,许多数据跟踪事件将“begin”和“end”对括起来,便于跟踪嵌套的 API 调用。 例如,在此跟踪中,“用户数据”字段如下所示:
"enter_01 <comm.DbDataAdapter.Fill|API> 1# dataSet"
"enter_02 <comm.DbDataAdapter.Fill|API> 1# dataSet startRecord
maxRecords srcTable command behavior=16{ds.CommandBehavior}"
"<sc.SqlCommand.get_Connection|API> 1#"
"<sc.SqlCommand.get_Connection|API> 1#"
"enter_03 <sc.SqlConnection.Open|API> 1#"
"enter_04 <prov.DbConnectionBase.Open|API> 1#"
"enter_05 <SNIInitialize|API|SNI> pmo: 00000000{void}"
... many events deleted
"leave_05"
"<sc.TdsParser.CreateSession|ADV> 1# created session 2"
"<prov.DbConnectionFactory.CreatePooledConnection|RES|CPOOL> 1# Pooled
database connection created."
"leave_04"
"leave_03"
非常简单地可以看到,名为 DataAdapter.Fill (DataSet 的用户程序) 在 DataAdapter.Fill 的其他重载中调用,该重载调用到 SqlConnection.Open 中,等等。 每个 enter_nn 事件都有相应的 leave_nn 事件。 在此示例中,你将跟踪对底层 SNI (SQL Server网络接口) 低级别协议事件的调用。 但是,“主流”跟踪器 System.Data.1 生成的用户数据的有趣括号格式是什么?
用户数据和 ADO.NET 跟踪
顾名思义,用户数据字段的内容和格式完全是用户 (在这种情况下,跟踪提供程序) 自由裁量权。 调用System.Data.dll和System.OracleClient.dll采用易于解码的特殊格式。 以上一个跟踪记录序列中的条目为例:
"enter_04 <prov.DbConnectionBase.Open|API> 1#"
这可以解码为:
<namespace abbreviation.classname.methodname|keyword> parms
因此,上面的示例表示存在对 System.Data.ProviderBase.DbConnectionBase 的 Open 方法的 API 调用。 使用缩写命名空间的原因是使输出的大小更小。 参数编号后跟井号 (1#) 的数字用于标识 DbConnectionBase 对象的特定实例;在处理复杂跟踪并监视许多实例时,这非常有用。 下面是几个有助于解码用户数据的图表:
表 1. .NET 跟踪点中使用的命名空间缩写
描述 | 缩写 | 命名空间 |
---|---|---|
SqlClient 托管提供程序 | Sc | System.Data.SqlClient |
OleDb 托管提供程序 | oledb | System.Data.OleDb |
Odbc 托管提供程序 | odbc | System.Data.Odbc |
Oracle 托管提供程序 | ora | System.Data.OracleClient |
DataSet/DataTable/Data* | ds | System.Data |
通用代码 | comn | System.Data.Common |
提供程序基实现类 | 箴 | System.Data.ProviderBase |
表 2. .NET 跟踪点中使用的类别
关键字 | 类别 |
API | 调用公共 API (方法、属性) |
OLEDB | 代码调用 OLEDB 组件 |
ODBC | 代码调用 ODBC API |
SNI | 代码调用 SNI |
ERR | 错误 |
WARN | 警告 |
INFO | 信息 |
Ret | 返回值,通常采用 API 格式|Ret |
THROW | 引发 新的 异常 (不适用于重新引发的异常) |
CATCH | 代码捕获异常 |
CPOOL | 连接池活动 |
ADV | 高级跟踪点 |
可以使用此信息对跟踪输出进行后处理并仅查看与 DataSet 相关的事件,或者在 OleDb 托管事件和 OLE DB 本机事件之间进行选择。 或者,可以将信息放在一起,以便与事件关联。 只需使用 LIKE 运算符进行简单的查询即可。 但是,数据跟踪还处于起步阶段,格式和内容的确切详细信息将来可能会更改。 随着功能的发展,请小心重新测试任何后处理代码。
配置跟踪的应用程序
在本文的开头,我提到配置 loader 注册表项的 :P字符串值。 仅需要手动配置,因为数据访问跟踪处于起步阶段。 具体而言,使用数据跟踪的程序员不应依赖于在将来的版本中手动配置此密钥。 它已受 ACL (安全访问控制列表的保护,) 仅可由管理员更新;在将来的版本中,它可能是只读的。
如果发出该警告,则仅配置 :P ath 值可使跟踪在给定计算机上运行的所有应用程序上可用。 例如,如果程序员在其计算机上运行 SQL Server 2005 实例和数据访问客户端,则启用 SNI 跟踪将跟踪来自两端的 SNI 调用。 这可以生成一些较大的输出,尽管在某些用例中,这可以正好是所需的输出类型。 可以将应用程序配置为在没有:P值时进行跟踪,或者如果存在:P值,则可以从跟踪中排除应用程序
如果没有 :P ath 值,将仅跟踪专门配置的应用程序。 可以将应用程序配置为“可跟踪”,方法是指定一个REG_SZ或REG_EXPAND_SZ条目,其中将程序main可执行文件的完整路径指定为值名称,并将AdoNetDiag.dll的完整路径指定为值。 还可以使用路径名称和 * 通配符将整个目录配置为可跟踪。
如果有 :P ath 值,可以通过添加REG_SZ或REG_EXPAND_SZ条目和 值 来限制跟踪特定目录中的应用程序或应用程序 : (单冒号) 。 允许在目录名称中使用通配符。 例如,包含目录名称 (C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\*) 以及 : 值的名称字段将使SQL Server Binn 目录中的所有程序 (如SQL Server、SQL 跟踪等) 显示在跟踪中。 如果我在应用程序所在的同一台计算机上运行SQL Server,这是我最经常想要的。 请记住,此时配置注册表项只是将数据跟踪提供程序命名为 DLL (,只有AdoNetDiag.dll从) 中进行选择;它不会打开跟踪。 这是一项特别有用的功能,因为可以在长时间运行的程序 ((如 Web 服务器或 Windows 服务)执行之前配置和设置数据跟踪,) 不启用它。 然后,可以在程序运行时使用 logman 打开和关闭跟踪,而不会干扰它。 不使用跟踪时,它不会受到性能的冲击。 如果要跟踪网络问题,则无需运行具有任何特殊跟踪标志的SQL Server来获取详细信息。
还可以配置将哪些提供程序信息跟踪到哪些文件,并在一定程度上控制确切跟踪的内容。 可以像使用 traceon.cmd 文件一样,将来自所有四个提供程序的输出跟踪到单个文件,也可以将它们分离到每个提供程序的一个文件中。 为此,可以使用 logman 实用工具创建命名跟踪。 下面是创建四个跟踪的示例:
logman create trace test1 -p System.Data.1
logman create trace test2 -p System.Data.OracleClient.1
logman create trace test3 -p SQLNCLI.1
logman create trace test4 -p System.Data.SNI.B1
除了从命令行使用 logman 外,还可以使用 性能日志和警报管理单元 来配置、运行和停止跟踪。 本文不介绍如何使用此 MMC 管理单元。
通过操作 logman control.guid 文件中的位,可以控制跟踪的内容。 如果为每个跟踪使用单个提供程序并采用默认值,则不需要有 control.guid 文件,如前面的示例所示,但 traceon.cmd 使用了一个。 若要刷新内存,下面是 control.guid 中的一行:
{914ABDE2-171E-C600-3348-C514171DE148} 0x00000000 0 System.Data.1
此行中的此信息包括:
提供程序指南 - 哪个 ETW 提供程序
控制位 - 在本例中为0x00000000
控件值 - 在本例中为 0
提供程序名称 - ETW 要求,但被 logman 实用工具忽略
通过在 “控制 位”和“ 控制值” 字段中设置位,可以创建用于预筛选事件的宏级机制。 有效值为:
0x0002 Regular tracepoints 0x0004 Execution flow (function enter/leave) 0x0080 Advanced Output
还有一点,只有 System.Data.1 才有特殊意义
0x1000 Connection Pooling specific trace
当然,这些位可以“OR”在一起。 如果指定了0x00000000,则假定0x00000006。
可以在控件值中设置两个可能的非默认值:
128 - Convert Unicode text to ASCII text (reduces etl file size)
64 - Disable tracing in this component
尽管控制位是位掩码,但必须将控件值设置为数字。 请注意,设置这些控制位不提供用于配置各个组件的精细机制,但旨在使筛选事件类型变得容易,而无需自行对 CSV 文件进行后期处理。
使用跟踪调试参数绑定问题
现在,我们已经快速概述了跟踪,我想提供一个简单的用例。 我经常使用 ODBC 跟踪来确定应用程序何时会“吃”丰富的错误消息并生成礼貌但相当“无信息”的消息。 此类应用程序代码如下所示:
string s = GetConnectionStringFromConfigFile();
using (SqlConnection conn = new SqlConnection(s))
using (SqlCommand cmd = new SqlCommand(
"select * from authors where au_id = @auid", conn))
{
// the error is hardcoded here but could have come from suboptimal
// editing in a graphic user interface
cmd.Parameters.Add("@auid", SqlDbType.Int);
cmd.Parameters[0].Value = 123456789;
SqlDataReader rdr = null;
try {
// some code that could fail goes here
conn.Open();
rdr = cmd.ExecuteReader();
while (rdr.Read())
Console.WriteLine(rdr[0]);
rdr.Close();
}
catch (Exception e) {
MessageBox.Show("polite error message");
}
}
在这种情况下,错误是由参数类型不匹配引起的,诊断错误的人员可能无权访问程序的源代码。 打开跟踪后,会看到如下所示的输出:
"enter_01 <sc.SqlCommand.ExecuteReader|API> 1#"
"<sc.SqlCommand.get_Connection|API> 1#"
"<sc.SqlCommand.get_Connection|API> 1#"
"<sc.TdsParser.CreateSession|ADV> 1# created session 3"
"<sc.TdsParserSessionPool.CreateSession|ADV> 1# adding session 3 to pool"
"<sc.TdsParserSessionPool.GetSession|ADV> 1# using session 3"
"<sc.TdsParser.GetSession|ADV> 1# getting session 3 from pool"
"<sc.SqlCommand.ExecuteReader|INFO> 1# Command executed as RPC."
"<sc.SqlCommand.get_Connection|API> 1#"
"leave_01"
"enter_01 <sc.SqlDataReader.Read|API> 1#"
"<sc.SqlError.SqlError|ERR> infoNumber=245 errorState=1 errorClass=16
errorMessage='Syntax error converting the varchar value '172-32-1176' to a
column of data type int.' procedure='' lineNumber=1"
"leave_01"
这直接显示存在参数值不匹配的情况。 示例和跟踪文件在文章代码中提供。 请注意,在这种情况下,跟踪文件更加紧凑,因为我们仅使用 System.Data.1 提供程序进行跟踪。
两个关键诊断方案
有时,数据跟踪可用于阐明可能需要数天或数周才能找到的问题。 一个示例是诊断资源回收问题。 有时,程序逻辑错误可能会导致程序最终连接不足或连接池过载。 例如,启动事务并创建一个从不调用 COMMIT 或 ROLLBACK 的逻辑路径会导致连接在事务处理的连接池中保留,直到事务超时。这会产生一些奇怪的连接池行为,使应用程序程序员 (和诊断) 感到困惑。 相关的方案可能只是无法关闭连接,使池程序无法完成该工作,并超时 -- 这是一种“欠佳”的关闭连接方法,可以说是温和的。 通过针对后处理的跟踪运行 SELECT 语句来监视连接池活动并将其与事务活动相关联,对于解决这些棘手的问题非常有帮助。 在这种情况下,“enter-leave”对尤其具有启发性,事务超时跟踪条目也具有启发性。
另一种情况是应用程序的连接时间似乎异常长。 由于网络库的配置方式,SQL Server可能会尝试通过 TCP/IP 进行连接,例如,在 TCP/IP 失败时,在客户端协议列表中使用命名管道或其他协议。 如果列表中的第一个协议由于超时而失败,则可能类似于连接缓慢或响应时间缓慢。 可以使用数据跟踪在图形中详细watch此内容,因为 SqlClient 和其他托管 .NET 数据提供程序的跟踪与来自非托管堆栈和网络的跟踪集成。 事件的整个进度甚至会用括号括在“enter-leave”块中,并带有时间戳,使你能够查看 Open () 调用所花费的时间。
我们几乎没有触及这个复杂而强大的功能的用途。 未来试验的一些想法是:
- 将跟踪集成到单元测试中
- 对 DataSet 和 DataReader 调用的比较分析,以确定 DataSet 在何处花费其时间
- 将数据跟踪与 ASP.NET 和其他 ETW 提供程序结合使用
- 使用 SQL Server ETW 提供程序执行合并的数据跟踪和SQL Server跟踪
- 诊断其他网络协议问题
内部数据跟踪
现在,可以使用食谱方法在 Microsoft 数据访问堆栈中设置、运行和解释跟踪。 但是,除了发出命令行脚本之外,到底发生了什么?
数据跟踪基于提供程序模型本身。 ADO.NET 数据提供程序或其他数据访问代码使用标准 API (这些 API 本身使用标准跟踪挂钩) 将跟踪信息馈送到模型中,将来可能会生成多个数据跟踪提供程序。 目前只有 AdoNetDiag 可用,但你可以想象数据跟踪使用者在粒度级别提供事件预筛选,或者使用不同的跟踪输出系统(如 OutputDebugString 或输出到 SQL Server 中),以便于搜索/查询。 甚至可以将数据跟踪挂接到 .NET System.Diagnostics.Trace。
ADO.NET 2.0 和 SQL Native Client 附带了适用于 Windows (ETW 事件跟踪) 系统的适配器。 可以从托管堆栈跟踪到非托管堆栈,然后返回,而不会发生任何阻碍。 ETW 是一种高性能跟踪系统,最初是为设备驱动程序编写器实现内核级跟踪而引入的。 下面是使用数据跟踪作为示例的 ETW 的高级说明。
什么是 ETW?
与 Windows 性能监视器 相比,Windows 事件跟踪旨在提供较低的开销跟踪。 ETW 占用的 CPU 通常不超过 5%,每秒最多可以记录 20,000 个事件。 它足够快,可以实时启用跟踪。 ETW 使用基于提供程序的模型;在这种情况下,提供程序是向事件系统发送事件的系统或应用程序组件。 事件提供程序的一些示例包括 Active Directory、IIS 和 ASP.NET。 ADO.NET 和 SQL Native Client 数据跟踪注册五个 ETW 事件提供程序。
- System.Data.1 — ADO.NET System.Data.dll 中的提供程序和类
- System.Data.OracleClient.1 — System.OracleClient.dll 中的 OracleClient 提供程序
- System.Data.SNI.B1 — System.Data 中的 SNI (在 .NET 2.0 Beta 2 中更改为 System.Data.SNI.1)
- SQLNCLI.1 - SQL Native Client 提供程序和 SQL Native Client 的 SNI
- ADONETDIAG。ETW - 提供来自 ETW 适配器本身的事件
ETW 提供程序日志生成每个事件的时间戳。 启动跟踪时,可以指定高分辨率时间戳或低分辨率时间戳。 在 traceon.cmd 文件中,我们已使用 -ct perf 选项选择了高分辨率时间戳。 在上面的“单文件”脚本中,我们选择了默认 (低分辨率) 时间戳。 ETW 选择高性能,而选择易用性。 使用 tracerpt.exe 格式化 ETW 跟踪会产生粗略解码。 记录了 ETL 文件的格式,并将各个跟踪提供程序的架构记录在 WMI 中,因此欢迎程序员构建自己的专用格式化程序。 使用 ETW 的一个很好的功能是,生成的跟踪可以与 ASP.NET 跟踪或低级别 OS 内核跟踪结合使用。 所有事件都可以按提供程序记录到单个文件进行关联,或记录到单独的文件。 有关 Windows 事件跟踪的信息,请参阅模式&做法站点的性能最佳做法概览页。
ETW 输出可由各种工具使用,如果这些工具都不能满足你的特定需求,你可以构建自己的工具。 此类使用者工具的一个示例是 logparser。 Logparser 不能只使用 ETW 的输出,而只能使用 IIS 日志文件和 Windows 事件日志等其他输出。 然后,Logparser 允许使用类似于 SQL 的语法查询事件。 Logparser 作为 IIS 6.0 资源工具包工具的一部分提供。
结论
在 ADO.NET 2.0 版本中,已在提供程序级别、网络协议级别以及数据库访问中使用的某些组件(如 ADO.NET DataSet)中添加了跟踪。 模型的灵活性将在未来适应不同的跟踪引擎,并且 API 非常简单,以便提供程序编写器和用户应用程序编写者可以向其产品添加跟踪。 当前的实现是将 ETW 与跟踪结合使用,并提供一种低级别、最小的中断方法来收集公开的跟踪点事件。 对跟踪数据进行后期处理或在执行时筛选跟踪的不同方式将允许内部软件支持诊断人员和 Microsoft 产品支持服务等不同组使用跟踪。
数据跟踪与当前跟踪收集设施的集成,以及未来跟踪收集设施的扩展性,使得在疑难解答和管理员的工具箱中成为有用且长期有效的工具。 祝你追踪愉快!
Bob Beauchemin 是 DevelopMentor 的讲师、课程作者和数据库课程联络人。 作为以数据为中心的分布式系统的架构师、程序员和管理员,他有超过 25 年的经验。 他撰写了有关 microsoft Systems Journal、SQL Server Magazine 等 ADO.NET、OLE DB 和 SQL Server 的文章,并且是 面向开发人员和基本 ADO.NET 的 2005 SQL Server初探。