共用方式為


在 SqlClient 中啟用事件追蹤

適用於:.NET Framework .NET .NET Standard

下載 ADO.NET

Windows 事件追蹤 (ETW) 是一種有效率的核心等級追蹤設施,可讓您記錄驅動程式定義的事件以進行偵錯及測試。 SqlClient 支援在不同資訊層級上擷取 ETW 事件。 若要開始擷取事件追蹤,用戶端應用程式應接聽 SqlClient EventSource 實作的事件:

Microsoft.Data.SqlClient.EventSource

目前的實作支援下列事件關鍵字:

關鍵字名稱 描述
ExecutionTrace 1 開啟/停止擷取命令執行前後的事件。
追蹤 2 開啟擷取基本應用程式流程追蹤事件。
影響範圍 4 開啟擷取輸入和結束事件
NotificationTrace 8 開啟擷取 SqlNotification 追蹤事件
NotificationTrace 16 開啟擷取 SqlNotification 範圍輸入和結束事件
PoolerTrace 32 開啟擷取連線集區流程追蹤事件。
PoolerScope 64 開啟擷取連線集區範圍追蹤事件。
AdvancedTrace 128 開啟擷取進階流程追蹤事件。
AdvancedTraceBin 256 開啟擷取包含其他資訊的進階流程追蹤事件。
CorrelationTrace 512 開啟擷取相互關聯流程追蹤事件。
StateDump 1024 開啟擷取 SqlConnection 的完整狀態傾印
SNITrace 2048 開啟擷取來自受控網路實作的流程追蹤事件 (僅適用於 .NET Core)
SNIScope 4096 開啟擷取來自受控網路實作的範圍事件 (僅適用於 .NET Core)

範例

下列範例會啟用 AdventureWorks 範例資料庫上資料作業的事件追蹤,並在主控台視窗中顯示事件。

using System;
using System.Diagnostics.Tracing;
using Microsoft.Data.SqlClient;

// This listener class will listen for events from the SqlClientEventSource class.
// SqlClientEventSource is an implementation of the EventSource class which gives 
// it the ability to create events.
public class SqlClientListener : EventListener
{
    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        // Only enable events from SqlClientEventSource.
        if (eventSource.Name.Equals("Microsoft.Data.SqlClient.EventSource"))
        {
            // Use EventKeyWord 2 to capture basic application flow events.
            // See the above table for all available keywords.
            EnableEvents(eventSource, EventLevel.Informational, (EventKeywords)2);
        }
    }

    // This callback runs whenever an event is written by SqlClientEventSource.
    // Event data is accessed through the EventWrittenEventArgs parameter.
    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        // Print event data.
        Console.WriteLine(eventData.Payload[0]);
    }
}

class Program
{
    public static void Main()
    {
        // Create a new event listener.
        using (SqlClientListener listener = new SqlClientListener())
        {
            string connectionString = "Data Source=localhost; " +
                "Initial Catalog=AdventureWorks; Integrated Security=true";

            // Open a connection to the AdventureWorks database.
            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                connection.Open();

                string sql = "SELECT * FROM Sales.Currency";
                SqlCommand command = new SqlCommand(sql, connection);

                // Perform a data operation on the server.
                SqlDataReader reader = command.ExecuteReader();
                while (reader.Read())
                {
                    // Read the data.
                }
                reader.Close();
            }
        }
    }
}

原生 SNI 中的事件追蹤支援

Microsoft.Data.SqlClient 從 v2.1 開始,在 Microsoft.Data.SqlClient.SNIMicrosoft.Data.SqlClient.SNI.runtime 中提供了事件追蹤支援。 您可以使用 Xperf (部分機器翻譯) 與 PerfView (英文) 工具,從原生 DLL 收集事件。

Microsoft.Data.SqlClient v3.0 開始,可以在用戶端應用程式中使用事件收集工具來啟用事件追蹤,而不需進行任何修改。

使用 Microsoft.Data.SqlClient v2.1 時,必須使用事件來源接聽程式來設定 EventCommand,以啟用事件追蹤。 適用於原生 SNI 的有效 EventCommand 值如下:


// Enables trace events:
EventSource.SendCommand(eventSource, (EventCommand)8192, null);

// Enables flow events:
EventSource.SendCommand(eventSource, (EventCommand)16384, null);

// Enables both trace and flow events:
EventSource.SendCommand(eventSource, (EventCommand)(8192 | 16384), null);

下列範例會在原生 SNI DLL 中啟用事件追蹤。

// Native SNI tracing example
using System;
using System.Diagnostics.Tracing;
using Microsoft.Data.SqlClient;

public class SqlClientListener : EventListener
{
    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        if (eventSource.Name.Equals("Microsoft.Data.SqlClient.EventSource"))
        {
            // Enables both trace and flow events
            EventSource.SendCommand(eventSource, (EventCommand)(8192 | 16384), null);
        }
    }
}

class Program
{
    static string connectionString = @"Data Source = localhost; Initial Catalog = AdventureWorks;Integrated Security=true;";

    static void Main(string[] args)
    {
        // Event source listener configuration is not required in v3.0 onwards.
        using (SqlClientListener listener = new SqlClientListener())
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
        }
    }
}

使用 Xperf 來收集追蹤資料

  1. 使用下列命令來啟動追蹤。

    xperf -start trace -f myTrace.etl -on *Microsoft.Data.SqlClient.EventSource
    
  2. 執行原生 SNI 追蹤範例,以連線到 SQL Server。

  3. 使用下列命令列來停止追蹤。

    xperf -stop trace
    
  4. 使用 PerfView 來開啟步驟 1 中所指定的 myTrace.etl 檔案。 您可以使用 Microsoft.Data.SqlClient.EventSource/SNIScopeMicrosoft.Data.SqlClient.EventSource/SNITrace 的事件名稱來找到 SNI 追蹤記錄。

    使用 PerfView 來檢視 SNI 追蹤檔案

使用 PerfView 來收集追蹤資料

  1. 從功能表列啟動 PerfView 並執行 Collect > Collect

  2. 設定追蹤檔案名稱、輸出路徑與提供者名稱。

    收集之前先設定 Perfview

  3. 開始收集。

  4. 執行原生 SNI 追蹤範例,以連線到 SQL Server。

  5. 從 PerfView 停止收集。 根據步驟 2 中的設定產生 PerfViewData.etl 檔案需要一些時間。

  6. 在 PerfView 中開啟 etl 檔案。 您可以使用 Microsoft.Data.SqlClient.EventSource/SNIScopeMicrosoft.Data.SqlClient.EventSource/SNITrace 的事件名稱來找到 SNI 追蹤記錄。

使用 dotnet-trace 來收集追蹤

在 Linux、macOS 或 Windows 上,dotnet-trace 可以用來擷取追蹤。 donet-trace 工具可以用來收集 .NET 應用程式的追蹤。 如需 dotnet-trace 的詳細資訊,請參閱 dotnet-trace 效能分析公用程式。dotnet-trace 所建立的追蹤可以在 PerfView 中檢視。

  1. 如果尚未安裝,請在用戶端機器上安裝 .NET SDK

  2. 安裝 dotnet-trace

  3. 執行 dotnet-trace。 --providers 參數需要為來自 Microsoft.Data.SqlClient 的追蹤指定提供者名稱和關鍵字。 關鍵字選項是事件關鍵字資料表中轉換成十六進位的關鍵字值的總和。 若要從應用程式開頭以 MyApplication 的詳細資訊層級收集所有事件,關鍵字的總和為 8191,以十六進位表示為 1FFF。 在此命令中,由 5 指定詳細資訊層級。

    dotnet-trace collect --providers Microsoft.Data.SqlClient.EventSource:1FFF:5 -- dotnet MyApplication.dll
    

    輸出如下:

    
    Provider Name                           Keywords            Level               Enabled By
    Microsoft.Data.SqlClient.EventSource    0x0000000000001FFF  Verbose(5)          --providers
    
    Launching: dotnet MyApplication.dll
    Process        : /usr/lib/dotnet/dotnet
    Output File    : /home/appuser/dotnet_20240927_102506.nettrace
    
    [00:00:00:00]   Recording trace 0.00     (B)
    Press <Enter> or <Ctrl+C> to exit...
    
    Trace completed.
    Process exited with code '1'.
    

    若要在執行中的應用程式上收集資訊層級的所有事件,請先找出應用程式的處理序識別碼。 然後在處理序上執行 dotnet-trace。 資訊層級由 4 指定。

    dotnet-trace ps
    8734  MyApplication  /home/appuser/MyApplication/MyApplication
    
    dotnet-trace collect -–process-id 8734 --providers Microsoft.Data.SqlClient.EventSource:1FFF:4
    

    單獨執行應用程式,直至問題重現。 如果是高 CPU 問題,通常執行 5-10 秒就足夠了。

    Provider Name                           Keywords            Level               Enabled By
    Microsoft.Data.SqlClient.EventSource    0x0000000000001FFF  LogAlways(0)        --providers
    
    Process        : /usr/lib/dotnet/dotnet
    Output File    : /home/appuser/dotnet_20240927_104154.nettrace
    
    [00:00:00:10]   Recording trace 4.096    (KB)
    Press <Enter> or <Ctrl+C> to exit...
    Stopping the trace. This may take several minutes depending on the application being traced.
    
    Trace completed.
    

    追蹤檔案名稱以 .nettrace 結尾。 如果不是在 Windows 上追蹤,請將檔案複製到 Windows 系統。 在 PerfView 中檢視追蹤檔案。

外部資源

如需如何跨平台追蹤 Microsoft.Data.SqlClient 的另一組範例,請參閱 CSS SQL 網路工具 Wiki (英文)。

如需事件追蹤的詳細資訊,請參閱下列資源。

資源 說明
EventSource 類別 用來建立 ETW 事件。
EventListener 類別 提供啟用和停用事件來源事件的方法。