Lacak operasi kustom dengan Application Insights .NET SDK
Azure Application Insights SDK secara otomatis melacak permintaan HTTP masuk dan panggilan ke layanan dependen, seperti permintaan HTTP dan kueri SQL. Pelacakan dan korelasi permintaan dan dependensi memberi Anda visibilitas ke dalam responsivitas dan keandalan seluruh aplikasi di semua layanan mikro yang menggabungkan aplikasi ini.
Ada kelas pola aplikasi yang tidak dapat didukung secara umum. Pemantauan yang tepat pada pola tersebut memerlukan instrumentasi kode manual. Artikel ini membahas beberapa pola yang mungkin memerlukan instrumentasi manual, seperti pemrosesan antrean kustom dan menjalankan tugas latar belakang yang berjalan lama.
Dokumen ini menyediakan panduan tentang cara melacak operasi kustom dengan Application Insights SDK. Dokumentasi ini relevan untuk:
- Application Insights untuk .NET (juga dikenal sebagai Base SDK) versi 2.4+.
- Application Insights untuk aplikasi web (menjalankan ASP.NET) versi 2.4+.
- Application Insights untuk ASP.NET Core versi 2.1+.
Gambaran Umum
Operasi adalah bagian logis dari pekerjaan yang dijalankan oleh aplikasi. Operasi memiliki nama, waktu mulai, durasi, hasil, dan konteks eksekusi seperti nama pengguna, properti, dan hasil. Jika operasi A dimulai oleh operasi B, maka operasi B ditetapkan sebagai induk untuk A. Operasi hanya dapat memiliki satu induk, tetapi dapat memiliki banyak operasi anak. Untuk informasi selengkapnya tentang operasi dan korelasi telemetri, lihat Korelasi telemetri Azure Application Insights.
Dalam Application Insights .NET SDK, operasi ini dijelaskan oleh OperationTelemetry kelas abstrak dan keturunannya RequestTelemetry dan DependencyTelemetry.
Pelacakan operasi masuk
Web SDK Application Insights secara otomatis mengumpulkan permintaan HTTP untuk aplikasi ASP.NET yang berjalan dalam pipeline IIS dan semua aplikasi ASP.NET Core. Ada solusi yang didukung komunitas untuk platform dan kerangka kerja lainnya. Namun, jika aplikasi tidak didukung oleh salah satu solusi standar atau didukung komunitas, Anda dapat membuat instrumen secara manual.
Contoh lain yang memerlukan pelacakan kustom adalah pekerja yang menerima item dari antrean. Untuk beberapa antrean, panggilan untuk menambahkan pesan ke antrean ini dilacak sebagai dependensi. Namun, operasi tingkat tinggi yang menjelaskan pemrosesan pesan tidak dikumpulkan secara otomatis.
Mari kita lihat cara operasi tersebut dapat dilacak.
Pada tingkat tinggi, tugasnya adalah membuat RequestTelemetry dan mengatur properti yang diketahui. Setelah operasi selesai, Anda lacak telemetrinya. Diagram berikut menunjukkan tugas ini.
Permintaan HTTP di aplikasi Owin yang dihosting sendiri
Dalam contoh ini, konteks jejak disebarkan sesuai dengan Protokol HTTP untuk Korelasi. Tunggu untuk menerima header yang dijelaskan di sana.
public class ApplicationInsightsMiddleware : OwinMiddleware
{
// you may create a new TelemetryConfiguration instance, reuse one you already have
// or fetch the instance created by Application Insights SDK.
private readonly TelemetryConfiguration telemetryConfiguration = TelemetryConfiguration.CreateDefault();
private readonly TelemetryClient telemetryClient = new TelemetryClient(telemetryConfiguration);
public ApplicationInsightsMiddleware(OwinMiddleware next) : base(next) {}
public override async Task Invoke(IOwinContext context)
{
// Let's create and start RequestTelemetry.
var requestTelemetry = new RequestTelemetry
{
Name = $"{context.Request.Method} {context.Request.Uri.GetLeftPart(UriPartial.Path)}"
};
// If there is a Request-Id received from the upstream service, set the telemetry context accordingly.
if (context.Request.Headers.ContainsKey("Request-Id"))
{
var requestId = context.Request.Headers.Get("Request-Id");
// Get the operation ID from the Request-Id (if you follow the HTTP Protocol for Correlation).
requestTelemetry.Context.Operation.Id = GetOperationId(requestId);
requestTelemetry.Context.Operation.ParentId = requestId;
}
// StartOperation is a helper method that allows correlation of
// current operations with nested operations/telemetry
// and initializes start time and duration on telemetry items.
var operation = telemetryClient.StartOperation(requestTelemetry);
// Process the request.
try
{
await Next.Invoke(context);
}
catch (Exception e)
{
requestTelemetry.Success = false;
telemetryClient.TrackException(e);
throw;
}
finally
{
// Update status code and success as appropriate.
if (context.Response != null)
{
requestTelemetry.ResponseCode = context.Response.StatusCode.ToString();
requestTelemetry.Success = context.Response.StatusCode >= 200 && context.Response.StatusCode <= 299;
}
else
{
requestTelemetry.Success = false;
}
// Now it's time to stop the operation (and track telemetry).
telemetryClient.StopOperation(operation);
}
}
public static string GetOperationId(string id)
{
// Returns the root ID from the '|' to the first '.' if any.
int rootEnd = id.IndexOf('.');
if (rootEnd < 0)
rootEnd = id.Length;
int rootStart = id[0] == '|' ? 1 : 0;
return id.Substring(rootStart, rootEnd - rootStart);
}
}
Protokol HTTP untuk Korelasi juga mendeklarasikan header Correlation-Context. Namun, itu dihilangkan di sini untuk penyederhanaan.
Instrumentasi antrean
Meskipun ada W3C Trace Context dan HTTP Protocol for Correlation untuk melewati detail korelasi dengan permintaan HTTP, setiap protokol antrean harus menentukan membedakan detail yang sama diteruskan di sepanjang pesan antrean. Beberapa protokol antrean (seperti AMQP) memungkinkan melewati metadata tambahan dan beberapa lainnya (seperti Antrean Azure Storage) memerlukan konteks untuk dikodekan ke dalam muatan pesan.
Catatan
- Pelacakan lintas komponen belum didukung untuk antrean Dengan HTTP, jika produsen dan konsumen Anda mengirim telemetri ke sumber daya Application Insights yang berbeda, Pengalaman Diagnostik Transaksi dan Peta Aplikasi menunjukkan transaksi dan pemetaan secara ujung-ke-ujung. Jika terjadi antrean, ini belum didukung.
Antrean Bus Layanan
Lihat Pelacakan dan korelasi terdistribusi melalui olahpesan Bus Layanan untuk melacak informasi.
Penting
Paket WindowsAzure.ServiceBus dan Microsoft.Azure.ServiceBus tidak digunakan lagi.
Antrean Azure Storage
Contoh berikut menunjukkan cara melacak operasi antrean Azure Storage dan menghubungkan telemetri antara produsen, konsumen, dan Azure Storage.
Antrean Penyimpanan memiliki HTTP API. Semua panggilan ke antrean dilacak oleh Kolektor Dependensi Application Insights untuk permintaan HTTP. Ini dikonfigurasi secara default pada aplikasi ASP.NET dan ASP.NET Core, dengan jenis aplikasi lain, Anda dapat merujuk ke dokumentasi aplikasi konsol
Anda juga mungkin ingin menghubungkan ID operasi Application Insights dengan ID permintaan Penyimpanan. Untuk informasi tentang cara mengatur dan mendapatkan klien permintaan Penyimpanan dan ID permintaan server, lihat Memantau, mendiagnosis, dan memecahkan masalah Azure Storage.
Masukkan Antrean
Karena antrean Penyimpanan mendukung HTTP API, semua operasi dengan antrean secara otomatis dilacak oleh Application Insights. Dalam banyak kasus, instrumentasi ini cukup. Namun, untuk menghubungkan jejak di sisi konsumen dengan jejak produsen, Anda harus melewati beberapa konteks korelasi yang sama dengan cara kami melakukannya dalam Protokol HTTP untuk Korelasi.
Contoh ini menunjukkan cara melacak operasi Enqueue. Anda dapat:
- Menyambungkan percobaan kembali (jika ada) : Mereka semua memiliki satu induk umum yaitu operasi
Enqueue. Jika tidak, mereka dilacak sebagai anak dari permintaan masuk. Jika ada beberapa permintaan logis untuk antrean, mungkin sulit untuk menemukan panggilan mana yang mengakibatkan percobaan kembali. - Menyambungkan log Penyimpanan (jika dan ketika diperlukan) : Mereka disambungkan dengan telemetri Application Insights.
Operasi Enqueue ini adalah anak dari operasi induk (misalnya, permintaan HTTP masuk). Panggilan dependensi HTTP adalah anak dari operasi Enqueue dan cucu dari permintaan masuk:
public async Task Enqueue(CloudQueue queue, string message)
{
var operation = telemetryClient.StartOperation<DependencyTelemetry>("enqueue " + queue.Name);
operation.Telemetry.Type = "Azure queue";
operation.Telemetry.Data = "Enqueue " + queue.Name;
// MessagePayload represents your custom message and also serializes correlation identifiers into payload.
// For example, if you choose to pass payload serialized to JSON, it might look like
// {'RootId' : 'some-id', 'ParentId' : '|some-id.1.2.3.', 'message' : 'your message to process'}
var jsonPayload = JsonConvert.SerializeObject(new MessagePayload
{
RootId = operation.Telemetry.Context.Operation.Id,
ParentId = operation.Telemetry.Id,
Payload = message
});
CloudQueueMessage queueMessage = new CloudQueueMessage(jsonPayload);
// Add operation.Telemetry.Id to the OperationContext to correlate Storage logs and Application Insights telemetry.
OperationContext context = new OperationContext { ClientRequestID = operation.Telemetry.Id};
try
{
await queue.AddMessageAsync(queueMessage, null, null, new QueueRequestOptions(), context);
}
catch (StorageException e)
{
operation.Telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
operation.Telemetry.Success = false;
operation.Telemetry.ResultCode = e.RequestInformation.HttpStatusCode.ToString();
telemetryClient.TrackException(e);
}
finally
{
// Update status code and success as appropriate.
telemetryClient.StopOperation(operation);
}
}
Untuk mengurangi jumlah telemetri laporan aplikasi Anda atau jika Anda tidak ingin melacak operasi Enqueue karena alasan lain, gunakan API Activity secara langsung:
- Buat (dan mulai)
Activitybaru daripada memulai operasi Application Insights. Anda tidak perlu menetapkan properti apa pun di atasnya kecuali nama operasi. - Pembuat serialisasi
yourActivity.Idke dalam muatan pesan daripadaoperation.Telemetry.Id. Anda juga dapat menggunakanActivity.Current.Id.
Keluarkan dari Antrean
Serupa dengan Enqueue, permintaan HTTP aktual ke antrean Penyimpanan secara otomatis dilacak oleh Application Insights. Namun, operasi Enqueue mungkin terjadi dalam konteks induk, seperti konteks permintaan masuk. Application Insights SDK secara otomatis menghubungkan operasi tersebut (dan bagian HTTP-nya) dengan permintaan induk dan telemetri lain yang dilaporkan dalam cakupan yang sama.
Operasi Dequeue rumit. Application Insights SDK secara otomatis melacak permintaan HTTP. Namun, tidak tahu konteks korelasi sampai pesan diurai. Tidak mungkin menyambungkan permintaan HTTP untuk mendapatkan pesan dengan sisa telemetri terutama ketika lebih dari satu pesan diterima.
public async Task<MessagePayload> Dequeue(CloudQueue queue)
{
var operation = telemetryClient.StartOperation<DependencyTelemetry>("dequeue " + queue.Name);
operation.Telemetry.Type = "Azure queue";
operation.Telemetry.Data = "Dequeue " + queue.Name;
try
{
var message = await queue.GetMessageAsync();
}
catch (StorageException e)
{
operation.telemetry.Properties.Add("AzureServiceRequestID", e.RequestInformation.ServiceRequestID);
operation.telemetry.Success = false;
operation.telemetry.ResultCode = e.RequestInformation.HttpStatusCode.ToString();
telemetryClient.TrackException(e);
}
finally
{
// Update status code and success as appropriate.
telemetryClient.StopOperation(operation);
}
return null;
}
Proses
Dalam contoh berikut, pesan masuk dilacak dengan cara yang sama dengan permintaan HTTP masuk:
public async Task Process(MessagePayload message)
{
// After the message is dequeued from the queue, create RequestTelemetry to track its processing.
RequestTelemetry requestTelemetry = new RequestTelemetry { Name = "process " + queueName };
// It might also make sense to get the name from the message.
requestTelemetry.Context.Operation.Id = message.RootId;
requestTelemetry.Context.Operation.ParentId = message.ParentId;
var operation = telemetryClient.StartOperation(requestTelemetry);
try
{
await ProcessMessage();
}
catch (Exception e)
{
telemetryClient.TrackException(e);
throw;
}
finally
{
// Update status code and success as appropriate.
telemetryClient.StopOperation(operation);
}
}
Demikian pula, operasi antrean lainnya dapat dijadikan instrumen. Operasi intip harus dijadikan instrumen dengan cara yang sama seperti operasi keluarkan dari antrean. Instrumentasi operasi manajemen antrean tidak diperlukan. Application Insights melacak operasi seperti HTTP, dan dalam banyak kasus, itu cukup.
Saat Anda menghapus pesan instrumen, pastikan Anda mengatur pengidentifikasi operasi (korelasi). Selain itu, Anda dapat menggunakan ActivityAPI. Maka Anda tidak perlu mengatur pengidentifikasi operasi pada item telemetri karena Application Insights SDK melakukannya untuk Anda:
- Buat
Activitybaru setelah Anda mendapatkan item dari antrean. - Gunakan
Activity.SetParentId(message.ParentId)untuk mengkorelasikan log konsumen dan produsen. - Mulai
Activity. - Lacak keluarkan dari antrean, proses, dan hapus operasi dengan menggunakan pembantu
Start/StopOperation. Lakukan dari alur kontrol asinkron yang sama (konteks eksekusi). Dengan cara ini, mereka berkorelasi dengan benar. - Hentikan
Activity. - Gunakan
Start/StopOperation, atau hubungiTracktelemetri secara manual.
Jenis Dependensi
Application Insights menggunakan jenis dependensi untuk menyesuaikan pengalaman UI. Untuk antrean, ia mengenali jenis-jenis DependencyTelemetry berikut yang meningkatkan Pengalaman diagnostik transaksi:
Azure queueuntuk Azure Storage QueuesAzure Event Hubsuntuk Azure Event HubsAzure Service Busuntuk Azure Service Bus
Pemrosesan batch
Dengan beberapa antrean, Anda dapat mengeluarkan beberapa pesan dari antrean dengan satu permintaan. Memproses pesan tersebut mungkin independen dan termasuk dalam operasi logis berbeda. Tidak mungkin untuk menghubungkan operasi Dequeue ke pesan tertentu yang sedang diproses.
Setiap pesan harus diproses dalam alur kontrol asinkronnya sendiri. Untuk informasi selengkapnya, lihat bagian Pelacakan dependensi keluar.
Tugas latar belakang yang berjalan lama
Beberapa aplikasi memulai operasi jangka panjang yang mungkin disebabkan oleh permintaan pengguna. Dari perspektif pelacakan/instrumentasi, tidak berbeda dengan instrumentasi permintaan atau dependensi:
async Task BackgroundTask()
{
var operation = telemetryClient.StartOperation<DependencyTelemetry>(taskName);
operation.Telemetry.Type = "Background";
try
{
int progress = 0;
while (progress < 100)
{
// Process the task.
telemetryClient.TrackTrace($"done {progress++}%");
}
// Update status code and success as appropriate.
}
catch (Exception e)
{
telemetryClient.TrackException(e);
// Update status code and success as appropriate.
throw;
}
finally
{
telemetryClient.StopOperation(operation);
}
}
Dalam contoh ini, telemetryClient.StartOperationmembuat DependencyTelemetry dan mengisi konteks korelasi. Semisal Anda memiliki operasi induk yang dibuat oleh permintaan masuk yang menjadwalkan operasi. Selama BackgroundTask dimulai dalam alur kontrol asinkron yang sama dengan permintaan masuk, upaya itu berkorelasi dengan operasi induk itu. BackgroundTask dan semua item telemetri bertumpuk secara otomatis berkorelasi dengan permintaan yang menyebabkannya, bahkan setelah permintaan berakhir.
Ketika tugas dimulai dari thread latar belakang yang tidak memiliki operasi apa pun (Activity) yang terkait dengannya, BackgroundTask tidak memiliki induk. Namun, ia dapat memiliki operasi bertumpuk. Semua item telemetri yang dilaporkan dari tugas berkorelasi dengan DependencyTelemetry yang dibuat di BackgroundTask.
Pelacakan dependensi keluar
Anda dapat melacak jenis dependensi Anda sendiri atau operasi yang tidak didukung oleh Application Insights.
Metode Enqueue dalam antrean Bus Layanan atau antrean Penyimpanan dapat berfungsi sebagai contoh untuk pelacakan kustom tersebut.
Pendekatan umum untuk pelacakan dependensi kustom adalah:
- Panggil metode
TelemetryClient.StartOperation(ekstensi) yang mengisi propertiDependencyTelemetryyang diperlukan untuk korelasi dan beberapa properti lainnya (stempel waktu mulai, durasi). - Atur properti kustom lainnya pada
DependencyTelemetry, seperti nama dan konteks lain yang Anda butuhkan. - Lakukan panggilan dependensi dan tunggu.
- Hentikan operasi
StopOperationketika sudah selesai. - Menangani pengecualian.
public async Task RunMyTaskAsync()
{
using (var operation = telemetryClient.StartOperation<DependencyTelemetry>("task 1"))
{
try
{
var myTask = await StartMyTaskAsync();
// Update status code and success as appropriate.
}
catch(...)
{
// Update status code and success as appropriate.
}
}
}
Operasi pembuangan menyebabkan operasi dihentikan, sehingga Anda dapat melakukannya daripada memanggil StopOperation.
Peringatan: dalam beberapa kasus, pengecualian tidak langsung dapat mencegahfinally dipanggil sehingga operasi tidak dapat dilacak.
Pemrosesan dan pelacakan operasi paralel
StopOperation hanya menghentikan operasi yang dimulai. Jika operasi yang berjalan saat ini tidak cocok dengan operasi yang ingin Anda hentikan, StopOperation tidak melakukan apa pun. Situasi ini mungkin terjadi jika Anda memulai beberapa operasi secara paralel dalam konteks eksekusi yang sama:
var firstOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 1");
var firstTask = RunMyTaskAsync();
var secondOperation = telemetryClient.StartOperation<DependencyTelemetry>("task 2");
var secondTask = RunMyTaskAsync();
await firstTask;
// FAILURE!!! This will do nothing and will not report telemetry for the first operation
// as currently secondOperation is active.
telemetryClient.StopOperation(firstOperation);
await secondTask;
Pastikan Anda selalu memanggil StartOperation dan memproses operasi dalam metode asinkron yang sama untuk mengisolasi operasi yang berjalan secara paralel. Jika operasi sinkron (atau tidak asinkron), bungkus proses dan lacak dengan Task.Run:
public void RunMyTask(string name)
{
using (var operation = telemetryClient.StartOperation<DependencyTelemetry>(name))
{
Process();
// Update status code and success as appropriate.
}
}
public async Task RunAllTasks()
{
var task1 = Task.Run(() => RunMyTask("task 1"));
var task2 = Task.Run(() => RunMyTask("task 2"));
await Task.WhenAll(task1, task2);
}
Operasi ApplicationInsights vs System.Diagnostics.Activity
System.Diagnostics.Activity mewakili konteks pelacakan terdistribusi dan digunakan oleh kerangka kerja dan pustaka untuk membuat dan menyebarkan konteks di dalam dan di luar proses dan menghubungkan item telemetri. Aktivitas bekerja sama dengan System.Diagnostics.DiagnosticSource - mekanisme pemberitahuan antara kerangka kerja/pustaka untuk memberi tahu tentang acara menarik (permintaan masuk atau keluar, pengecualian, dll).
Aktivitas adalah warga kelas satu dalam Application Insights dan dependensi otomatis dan pengumpulan permintaan sangat bergantung pada mereka bersama dengan acara DiagnosticSource. Jika Anda membuat Aktivitas di aplikasi Anda - aktivitas tidak akan mengakibatkan telemetri Application Insights dibuat. Application Insights perlu menerima acara DiagnosticSource dan mengetahui nama dan muatan acara untuk menerjemahkan Aktivitas ke dalam telemetri.
Setiap operasi Application Insights (permintaan atau dependensi) melibatkan Activity - ketika StartOperation dipanggil, upaya itu menciptakan Aktivitas di bawahnya. StartOperation adalah cara yang disarankan untuk melacak telemetri permintaan atau dependensi secara manual dan memastikan semuanya berkorelasi.
Langkah berikutnya
- Pelajari dasar-dasar korelasi telemetri dalam Application Insights.
- Lihat cara data berkorelasi menggerakkan Pengalaman Diagnostik Transaksi dan Peta Aplikasi.
- Lihat model data untuk model data dan jenis Application Insights.
- laporkan acara dan metrik kustom ke Application Insights.
- Lihat konfigurasi standar untuk koleksi properti konteks.
- Periksa Panduan Pengguna System.Diagnostics.Activity untuk melihat cara kami menyambungkan telemetri.