Konsep pelacakan terdistribusi .NET
Pelacakan terdistribusi adalah teknik diagnostik yang membantu teknisi melokalisasi kegagalan dan masalah performa dalam aplikasi, terutama yang dapat didistribusikan di beberapa mesin atau proses. Lihat Gambaran Umum Pelacakan Terdistribusi untuk informasi umum tentang di mana pelacakan terdistribusi berguna.
Jejak dan Aktivitas
Setiap kali permintaan baru diterima oleh aplikasi, permintaan tersebut dapat dikaitkan dengan jejak. Dalam komponen aplikasi yang ditulis dalam .NET, unit pekerjaan dalam jejak diwakili oleh instans System.Diagnostics.Activity dan jejak secara keseluruhan membentuk pohon Dari Aktivitas ini, berpotensi mencakup banyak proses yang berbeda. Aktivitas pertama yang dibuat untuk permintaan baru membentuk akar pohon pelacakan dan melacak durasi keseluruhan dan keberhasilan/kegagalan menangani permintaan. Aktivitas anak dapat dibuat secara opsional untuk membalikkan pekerjaan ke dalam berbagai langkah yang dapat dilacak secara individual. Misalnya, mengingat Aktivitas yang melacak permintaan HTTP masuk tertentu di server web, aktivitas anak dapat dibuat untuk melacak setiap kueri database yang diperlukan untuk menyelesaikan permintaan. Ini memungkinkan durasi dan keberhasilan untuk setiap kueri direkam secara independen. Aktivitas dapat merekam informasi lain untuk setiap unit kerja seperti OperationName, pasangan nama-nilai yang disebut Tags, dan Events. Nama mengidentifikasi jenis pekerjaan yang sedang dilakukan, tag dapat merekam parameter deskriptif pekerjaan, dan peristiwa adalah mekanisme pengelogan sederhana untuk merekam pesan diagnostik bertanda waktu.
Catatan
Nama industri umum lainnya untuk unit pekerjaan dalam jejak terdistribusi adalah 'Rentang'. .NET mengadopsi istilah 'Aktivitas' bertahun-tahun yang lalu, sebelum nama 'Rentang' dibuat dengan baik untuk konsep ini.
ID Aktivitas
Hubungan Induk-Turunan antara Aktivitas di pohon pelacakan terdistribusi dibuat menggunakan ID unik. . Implementasi PELACAKAN terdistribusi NET mendukung dua skema ID: TraceContext standar W3C, yang merupakan default dalam .NET 5+, dan konvensi .NET yang lebih lama yang disebut 'Hierarkis' yang tersedia untuk kompatibilitas mundur. Activity.DefaultIdFormat mengontrol skema ID mana yang digunakan. Dalam standar W3C TraceContext, setiap jejak diberi id jejak 16 byte unik secara global (Activity.TraceId), dan setiap Aktivitas dalam jejak diberi id rentang 8 byte unik (Activity.SpanId). Setiap Aktivitas mencatat trace-id, span-id-nya sendiri, dan rentang-id induknya (Activity.ParentSpanId). Karena jejak terdistribusi dapat melacak pekerjaan di seluruh batas proses, Aktivitas induk dan anak mungkin tidak berada dalam proses yang sama. Kombinasi trace-id dan id rentang induk dapat secara unik mengidentifikasi Aktivitas induk secara global, terlepas dari proses apa yang ada di dalamnya.
Activity.DefaultIdFormat mengontrol format ID mana yang digunakan untuk memulai jejak baru, tetapi secara default menambahkan Aktivitas baru ke jejak yang ada menggunakan format apa pun yang digunakan Aktivitas induk. Pengaturan Activity.ForceDefaultIdFormat ke true mengambil alih perilaku ini dan membuat semua Aktivitas baru dengan DefaultIdFormat, bahkan ketika induk menggunakan format ID yang berbeda.
Memulai dan menghentikan Aktivitas
Setiap utas dalam proses mungkin memiliki objek Aktivitas yang sesuai yang melacak pekerjaan yang terjadi pada utas tersebut, dapat diakses melalui Activity.Current. Aktivitas saat ini secara otomatis mengalir di sepanjang semua panggilan sinkron pada utas dan mengikuti panggilan asinkron yang diproses pada utas yang berbeda. Jika Aktivitas A adalah aktivitas saat ini pada utas dan kode memulai Aktivitas B baru, maka B menjadi aktivitas baru saat ini pada utas tersebut. Secara default, aktivitas B juga akan memperlakukan Aktivitas A sebagai induknya. Ketika Aktivitas B kemudian dihentikan, aktivitas A akan dipulihkan sebagai Aktivitas saat ini pada utas. Ketika Aktivitas dimulai, Aktivitas mengambil waktu saat ini sebagai Activity.StartTimeUtc. Ketika berhenti, Activity.Duration dihitung sebagai perbedaan antara waktu saat ini dan waktu mulai.
Berkoordinasi di seluruh batas proses
Untuk melacak pekerjaan di seluruh batas proses, ID induk Aktivitas perlu ditransmisikan di seluruh jaringan sehingga proses penerimaan dapat membuat Aktivitas yang merujuknya. Saat menggunakan format ID W3C TraceContext, .NET juga menggunakan header HTTP yang direkomendasikan oleh standar untuk mengirimkan informasi ini. Saat menggunakan Hierarchical format ID, .NET menggunakan header HTTP request-id kustom untuk mengirimkan ID. Tidak seperti banyak runtime bahasa lain, pustaka dalam kotak .NET seperti server web ASP.NET dan System.Net.Http secara asli memahami cara mendekode dan mengodekan ID Aktivitas pada pesan HTTP. Runtime juga memahami cara mengalirkan ID melalui panggilan sinkron dan asinkron. Ini berarti bahwa aplikasi .NET yang menerima dan memancarkan pesan HTTP berpartisipasi dalam mengalirkan ID jejak terdistribusi secara otomatis, tanpa pengkodean khusus oleh pengembang aplikasi atau dependensi pustaka pihak ketiga. Pustaka pihak ketiga dapat menambahkan dukungan untuk mengirimkan ID melalui protokol pesan non-HTTP atau mendukung konvensi pengodean kustom untuk HTTP.
Mengumpulkan jejak
Kode berinstrumen dapat membuat Activity objek sebagai bagian dari jejak terdistribusi, tetapi informasi dalam objek ini perlu ditransmisikan dan diserialisasikan di penyimpanan persisten terpusat sehingga seluruh jejak dapat ditinjau secara berguna nanti. Ada beberapa pustaka koleksi telemetri yang dapat melakukan tugas ini seperti Application Insights, OpenTelemetry, atau pustaka yang disediakan oleh telemetri pihak ketiga atau vendor APM. Secara bergantian, pengembang dapat menulis koleksi telemetri Aktivitas kustom mereka sendiri dengan menggunakan System.Diagnostics.ActivityListener atau System.Diagnostics.DiagnosticListener. ActivityListener mendukung pengamatan Aktivitas apa pun terlepas dari apakah pengembang memiliki pengetahuan sebelumnya tentang hal itu. Ini menjadikan ActivityListener solusi tujuan umum yang sederhana dan fleksibel. Sebaliknya, menggunakan DiagnosticListener adalah skenario yang lebih kompleks yang mengharuskan kode berinstrumen untuk ikut serta dengan memanggil DiagnosticSource.StartActivity dan pustaka koleksi perlu mengetahui informasi penamaan yang tepat yang digunakan kode berinstrumen saat memulainya. Menggunakan DiagnosticSource dan DiagnosticListener memungkinkan pembuat dan pendengar untuk bertukar objek .NET arbitrer dan membuat konvensi lolos informasi yang disesuaikan.
Pengambilan sampel
Untuk peningkatan performa dalam aplikasi throughput tinggi, pelacakan terdistribusi pada .NET hanya mendukung pengambilan sampel subset jejak daripada merekam semuanya. Untuk aktivitas yang dibuat dengan API yang direkomendasikan ActivitySource.StartActivity , pustaka pengumpulan telemetri dapat mengontrol pengambilan sampel dengan ActivityListener.Sample panggilan balik. Pustaka pengelogan dapat memilih untuk tidak membuat Aktivitas sama sekali, untuk membuatnya dengan informasi minimal yang diperlukan untuk menyebarkan ID pelacakan, atau untuk mengisinya dengan informasi diagnostik lengkap. Pilihan ini menukar meningkatkan overhead performa untuk meningkatkan utilitas diagnostik. Aktivitas yang mulai menggunakan pola pemanggilan Activity.Activity yang lebih lama dan DiagnosticSource.StartActivity juga dapat mendukung pengambilan sampel DiagnosticListener dengan terlebih dahulu memanggil DiagnosticSource.IsEnabled. Bahkan ketika menangkap informasi diagnostik penuh, implementasi .NET dirancang agar cepat - ditambah dengan kolektor yang efisien, Aktivitas dapat dibuat, diisi, dan ditransmisikan dalam sekitar mikrodetik pada perangkat keras modern. Pengambilan sampel dapat mengurangi biaya instrumentasi menjadi kurang dari 100 nanodetik untuk setiap Aktivitas yang tidak direkam.
Langkah berikutnya
Misalnya kode untuk mulai menggunakan pelacakan terdistribusi dalam aplikasi .NET, lihat Instrumentasi Pelacakan Terdistribusi.