Bahasa

Mengonfigurasi pelacakan terdistribusi di .NET

Dalam .NET 11 dan yang lebih baru, Microsoft.Extensions.Diagnostics.Tracing API memungkinkan Anda mendaftarkan ActivityListener instans dan menggunakan aturan untuk memilih ActivitySource dan Activity instans yang diterima setiap pendengar. Tentukan aturan dalam kode atau muat aturan tersebut dari IConfiguration.

Important

Aturan pelacakan hanya memengaruhi pendengar yang terdaftar melalui infrastruktur pelacakan ini. Mereka tidak memengaruhi instans yang tidak terkait ActivityListener , termasuk listener yang dibuat dan dikelola eksportir telemetri. Konfigurasikan listener-listener atau eksportir-eksportir tersebut secara terpisah.

Pelacakan register

API tersedia dalam Microsoft.Extensions.Diagnostics paket. Aplikasi yang mereferensikan Microsoft.AspNetCore.App kerangka kerja bersama sudah menyertakan assembly.

Panggil AddTracing di IServiceCollection. Dalam callback:

  • Gunakan AddListener untuk mendaftarkan setiap listener. Nama listener mengidentifikasi listener dalam aturan konfigurasi.
  • Konfigurasikan pengambilan sampel dan delegate notifikasi listener melalui ActivityListenerBuilder. Infrastruktur pelacakan mengelola ShouldListenTo, langganan sumber, dan masa pakai pendengar.
  • Panggil AddConfiguration dengan bagian konfigurasi yang berisi aturan. Untuk bagian bernama Tracing, berikan configuration.GetSection("Tracing").

Sampel lengkap menunjukkan ketiga panggilan. .NET host mengaktifkan langganan pelacakan saat host dimulai. Jika Anda menggunakan injeksi dependensi tanpa host, resolve ActivitySourceFactory yang terdaftar untuk membuat pendengar dan mengaktifkan langganan mereka. Contoh lengkap menentukan factory secara langsung.

Konfigurasi pelacakan

Atur aturan pelacakan melalui konfigurasi atau dalam kode. Jika tidak ada aturan yang cocok dengan pendengar, sumber, operasi, dan cakupan, pelacakan tetap dinonaktifkan untuk kombinasi tersebut.

Mengonfigurasi pelacakan tanpa kode

Untuk aplikasi yang menggunakan konfigurasi, tambahkan bagian Tracing ke appsettings.json atau penyedia konfigurasi lain. Kemudian teruskan bagian tersebut ke AddConfiguration:

tracing.AddConfiguration(configuration.GetSection("Tracing"));

Contoh berikut menunjukkan bagian aturan dan tingkat aturan yang didukung:

{
  "Tracing": {
    "EnabledTracing": {
      "Default": false,
      "Contoso": true,
      "Contoso.Orders": {
        "Default": true,
        "HealthCheck": false
      },
      "Contoso.*.Storage": true
    },
    "EnabledGlobalTracing": {
      "System.Net.Http": true
    },
    "EnabledLocalTracing": {
      "Contoso.Workers": true
    },
    "Console": {
      "EnabledLocalTracing": {
        "Contoso.Orders": {
          "Submit": false
        }
      }
    }
  }
}

Tambahkan aturan langsung di bawah bagian EnabledTracing, EnabledGlobalTracing, atau EnabledLocalTracing. Jangan tambahkan level Rules.

Bagian aturan

Pilih bagian aturan berdasarkan cakupan sumber dan apakah aturan menargetkan satu pendengar:

Bagian Pendengar yang sesuai Sumber aktivitas pencocokan
EnabledTracing Semua listener terdaftar. Sumber global dan lokal.
EnabledGlobalTracing Semua pendengar yang terdaftar. Sumber global saja.
EnabledLocalTracing Semua pendengar yang terdaftar. Sumber lokal saja.
{Listener}:EnabledTracing Listener bernama. Sumber global dan lokal.
{Listener}:EnabledGlobalTracing listener bernama. Sumber global saja.
{Listener}:EnabledLocalTracing Listener bernama tersebut. Sumber lokal saja.

Nama pendengar cocok dengan nama yang diteruskan ke AddListener. Nama bagian dan nama listener tidak peka terhadap huruf besar/kecil.

Tingkat aturan

Di bawah bagian aturan apa pun, gunakan salah satu format kunci berikut:

Formulir utama Tingkat aturan Cocokkan
Default Default. Setiap sumber data dan operasi.
{SourceName} Sumber aktivitas. Setiap operasi pencocokan sumber.
{SourceName}:Default Sumber aktivitas. Setiap operasi dari sumber yang sesuai. Formulir ini memungkinkan source juga berisi aturan operasi.
{SourceName}:{OperationName} Operasi. Operasi bernama dari sumber yang sesuai.

Atur setiap nilai daun ke true untuk mengaktifkan kecocokan atau false untuk menonaktifkannya. Misalnya, konfigurasi sebelumnya:

  • Menonaktifkan pelacakan secara default.
  • Mengaktifkan sumber yang namanya dimulai dengan Contoso.
  • Mengaktifkan Contoso.Orders, tetapi menonaktifkan operasi HealthCheck-nya.
  • Mengaktifkan pola sumber yang dimulai dengan Contoso. dan diakhir dengan .Storage.
  • Menambahkan aturan yang hanya berlaku untuk sumber global, sumber lokal, atau pendengar bernama Console.

Gunakan Default sebagai leaf Boolean. Jika Default berisi anak operasi, konfigurasi memperlakukan Default sebagai nama sumber aktivitas harfiah.

Mengonfigurasi pelacakan dengan kode

Panggil EnableTracing dan DisableTracing pada ITracingBuilder yang diteruskan ke AddTracing.

tracing.EnableTracing(sourceName: "Contoso");
tracing.DisableTracing(
    sourceName: "Contoso.Orders",
    operationName: "HealthCheck");

Kosongkan sourceName, operationName, atau listenerName untuk mencocokkan semua nilai pada tingkat tersebut. Secara default, aturan terprogram berlaku untuk sumber global dan lokal. Teruskan Global, Local, atau keduanya melalui argumen scopes untuk mempersempit aturan.

Aturan konfigurasi dan aturan programatis membentuk satu seperangkat aturan yang diurutkan. Jika aturan yang sama-sama spesifik bertentangan, aturan yang ditambahkan terakhir yang menang. Urutan panggilan dalam AddTracing panggilan balik oleh karena itu penting ketika AddConfiguration, EnableTracing, dan DisableTracing menambahkan aturan yang sama spesifiknya.

Pencocokan nama sumber aktivitas

Nama sumber, nama operasi, dan nama listener menggunakan perbandingan ordinal yang tidak peka huruf besar/kecil. Aturan nama sumber mendukung bentuk pencocokan ini:

  • Nama sumber kosong akan cocok dengan semua sumber.
  • Nama sumber tanpa wildcard cocok berdasarkan prefiks. Misalnya, Contoso cocok dengan Contoso.Orders dan ContosoPayments; pencocok tidak memerlukan pemisah setelah awalan.
  • Nama sumber dengan satu * wildcard cocok dengan awalan dan akhiran. Misalnya, Contoso.*.Storage cocok dengan Contoso.Orders.Storage, tetapi tidak Contoso.Orders.Api.
  • Nama sumber * cocok dengan setiap sumber.

Nama operasi sama persis. Mereka tidak menggunakan awalan atau pencocokan wildcard.

Terapkan prioritas aturan

Untuk setiap kombinasi pendengar, sumber, operasi, dan cakupan, infrastruktur pelacakan memilih satu aturan yang cocok. Ini membandingkan aturan pencocokan dalam urutan ini:

  • Aturan khusus pendengar lebih diutamakan daripada aturan untuk semua pendengar.
  • Aturan sumber lebih diutamakan daripada aturan default. Jika dua ekspresi sumber cocok, ekspresi yang lebih panjang lebih diutamakan. Perbandingan menggunakan panjang ekspresi, termasuk * wildcard.
  • Aturan operasi lebih diutamakan daripada aturan tingkat sumber.
  • Aturan khusus global saja atau lokal saja lebih diutamakan daripada aturan yang mencakup kedua cakupan.
  • Aturan terakhir lebih diutamakan ketika semua faktor sebelumnya sama.

Perbandingan berhenti pada perbedaan pertama. Misalnya, aturan default khusus listener lebih diutamakan daripada aturan khusus source yang berlaku untuk semua listener karena kekhususan listener dievaluasi terlebih dahulu.

Aturan operasi juga mengontrol subskripsi sumber. Listener berlangganan ke sumber yang secara default dinonaktifkan ketika aturan operasi mengaktifkan setidaknya satu operasi dari sumber tersebut. Listener kemudian mengembalikan None dan melewati panggilan baliknya untuk operasi yang dinonaktifkan.

Memilih sumber aktivitas global atau lokal

Infrastruktur pelacakan membedakan dua cakupan sumber aktivitas:

  • Sumber global adalah sebuah ActivitySource yang dibuat melalui konstruktornya. EnabledGlobalTracing aturan-aturan berlaku untuk sumber-sumber ini.
  • Sumber lokal adalah yang ActivitySource dibuat oleh ActivitySourceFactory yang di-resolve melalui injeksi dependensi. EnabledLocalTracing aturan berlaku untuk sumber daya yang dibuat oleh pabrik tersebut.

Gunakan Create saat Anda ingin container dependency injection mengelola sumber dan listener pelacakan. Listener pabrik mengabaikan sumber lokal yang dibuat oleh pabrik yang berbeda. Aturan dalam EnabledTracing berlaku untuk kedua jenis sumber.

Cakupan ini hanya membatasi pendengar yang AddTracing daftarkan. Pelacak independen ActivityListener menggunakan ShouldListenTo dan panggilan balik pengambilan sampelnya sendiri, bahkan untuk sumber aktivitas yang dibuat oleh ActivitySourceFactory.

Muat ulang konfigurasi pelacakan

AddConfiguration berlangganan ke token perubahan dari konfigurasi yang disediakan. Saat penyedia konfigurasi mendukung muat ulang dan melaporkan perubahan, infrastruktur pelacakan:

  • Membangun kembali kumpulan aturan.
  • Menyegarkan langganan sumber setiap pendengar terdaftar.
  • Menerapkan aturan yang diperbarui untuk aktivitas berikutnya.

Aplikasi dapat terus menggunakan instans yang sama ActivitySource setelah dimuat ulang. Aktivitas berikutnya menggunakan aturan yang diperbarui.

Untuk penyedia yang dapat diubah yang tidak melaporkan perubahan secara otomatis, perbarui konfigurasi dan panggil Reload. Sampel lengkap menggunakan pendekatan ini dengan penyedia konfigurasi dalam memori.

Menangani konfigurasi tidak valid

Konfigurasi pelacakan mengurai nilai dengan TryParse. Ini menerima true dan false tanpa membedakan huruf besar/kecil dan mengizinkan spasi di sekitarnya. Ini tidak menerima 1, , 0, yesatau on.

Pemuat konfigurasi secara diam-diam mengabaikan nilai daun yang bukan Boolean yang valid. Ini juga mengabaikan bagian yang tidak diketahui atau salah format yang tidak cocok dengan skema yang didukung. Periksa nama kunci dengan hati-hati karena kasus ini tidak menghasilkan pengecualian.

Ekspresi sumber dapat berisi paling banyak satu * wildcard. Aturan dengan lebih dari satu wildcard melempar ArgumentException pengecualian saat aturan diinstansiasi, baik selama startup aplikasi atau setelah konfigurasi dimuat ulang. Untuk aturan terprogram, None juga menyebabkan ArgumentOutOfRangeException.

Jalankan sampel

Aplikasi konsol .NET 11 berikut membuat satu operasi yang diaktifkan dan satu operasi yang dinonaktifkan. Sistem kemudian memperbarui aturan operasi yang dinonaktifkan, memanggil Reload, dan memulai operasi lagi melalui ActivitySource lokal yang sama.

using System.Diagnostics;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.Tracing;

IConfigurationRoot configuration = new ConfigurationBuilder()
    .AddInMemoryCollection(new Dictionary<string, string?>
    {
        ["Tracing:EnabledTracing:Default"] = "false",
        ["Tracing:EnabledTracing:Contoso.Orders:Default"] = "true",
        ["Tracing:EnabledTracing:Contoso.Orders:DisabledOperation"] = "false",
    })
    .Build();

ServiceCollection services = new();
services.AddTracing(tracing =>
{
    tracing.AddListener("Console", listener =>
    {
        listener.Sample = static (ref ActivityCreationOptions<ActivityContext> _) =>
            ActivitySamplingResult.AllData;
        listener.SampleUsingParentId = static (ref ActivityCreationOptions<string> _) =>
            ActivitySamplingResult.AllData;
        listener.ActivityStarted = activity =>
            Console.WriteLine($"Listener started: {activity.OperationName}");
    });
    tracing.AddConfiguration(configuration.GetSection("Tracing"));
});

using ServiceProvider serviceProvider = services.BuildServiceProvider();
ActivitySourceFactory factory =
    serviceProvider.GetRequiredService<ActivitySourceFactory>();
using ActivitySource source = factory.Create("Contoso.Orders");

Console.WriteLine("Before reload:");
WriteResult(source, "EnabledOperation");
WriteResult(source, "DisabledOperation");

configuration["Tracing:EnabledTracing:Contoso.Orders:DisabledOperation"] = "true";
configuration.Reload();

Console.WriteLine("After reload:");
WriteResult(source, "DisabledOperation");

static void WriteResult(ActivitySource source, string operationName)
{
    using Activity? activity = source.StartActivity(operationName);
    string state = activity is null ? "disabled" : "enabled";
    Console.WriteLine($"{operationName}: {state}");
}
Imports System.Diagnostics
Imports Microsoft.Extensions.Configuration
Imports Microsoft.Extensions.DependencyInjection
Imports Microsoft.Extensions.Diagnostics.Tracing

Module Program
    Sub Main()
        Dim initialData As New Dictionary(Of String, String) From {
            {"Tracing:EnabledTracing:Default", "false"},
            {"Tracing:EnabledTracing:Contoso.Orders:Default", "true"},
            {"Tracing:EnabledTracing:Contoso.Orders:DisabledOperation", "false"}
        }

        Dim configuration As IConfigurationRoot =
            New ConfigurationBuilder().AddInMemoryCollection(initialData).Build()

        Dim services As New ServiceCollection()
        services.AddTracing(
            Sub(tracing)
                tracing.AddListener(
                    "Console",
                    Sub(listener)
                        listener.Sample = AddressOf SampleActivity
                        listener.SampleUsingParentId = AddressOf SampleActivityUsingParentId
                        listener.ActivityStarted =
                            Sub(activity) Console.WriteLine(
                                $"Listener started: {activity.OperationName}")
                    End Sub)
                tracing.AddConfiguration(configuration.GetSection("Tracing"))
            End Sub)

        Using serviceProvider As ServiceProvider = services.BuildServiceProvider()
            Dim factory As ActivitySourceFactory =
                serviceProvider.GetRequiredService(Of ActivitySourceFactory)()

            Using source As ActivitySource = factory.Create("Contoso.Orders")
                Console.WriteLine("Before reload:")
                WriteResult(source, "EnabledOperation")
                WriteResult(source, "DisabledOperation")

                configuration(
                    "Tracing:EnabledTracing:Contoso.Orders:DisabledOperation") = "true"
                configuration.Reload()

                Console.WriteLine("After reload:")
                WriteResult(source, "DisabledOperation")
            End Using
        End Using
    End Sub

    Private Function SampleActivity(
        ByRef options As ActivityCreationOptions(Of ActivityContext)
    ) As ActivitySamplingResult
        Return ActivitySamplingResult.AllData
    End Function

    Private Function SampleActivityUsingParentId(
        ByRef options As ActivityCreationOptions(Of String)
    ) As ActivitySamplingResult
        Return ActivitySamplingResult.AllData
    End Function

    Private Sub WriteResult(source As ActivitySource, operationName As String)
        Using activity As Activity = source.StartActivity(operationName)
            Dim state As String = If(activity Is Nothing, "disabled", "enabled")
            Console.WriteLine($"{operationName}: {state}")
        End Using
    End Sub
End Module

Sampel C# dan Visual Basic menghasilkan hasil yang sama:

Before reload:
Listener started: EnabledOperation
EnabledOperation: enabled
DisabledOperation: disabled
After reload:
Listener started: DisabledOperation
DisabledOperation: enabled

Baca juga