Diagnostik Fungsi Tahan Lama di Azure
Ada beberapa opsi untuk mendiagnosis masalah dengan Durable Functions. Beberapa opsi tersebut sama, untuk fungsi reguler dan beberapa di antaranya khusus untuk Fungsi Tahan Lama.
Application Insights
Application Insights adalah cara yang disarankan untuk melakukan diagnostik dan pemantauan di Azure Functions. Hal yang sama berlaku untuk Durable Functions. Untuk gambaran umum cara memanfaatkan Application Insights di aplikasi fungsi Anda, lihat Memantau Azure Functions.
Ekstensi Azure Functions Durable juga memancarkan peristiwa pelacakan yang memungkinkan Anda melacak eksekusi end-to-end dari suatu orkestrasi. Peristiwa pelacakan ini dapat ditemukan dan dikuerikan menggunakan alat Application Insights Analytics di portal Azure.
Melacak data
Setiap peristiwa siklus hidup instans orkestrasi menyebabkan peristiwa pelacakan ditulis ke kumpulan jejak di Application Insights. Peristiwa ini berisi payload customDimensions dengan beberapa bidang. Nama bidang semuanya telah dibuka dengan prop__
.
- hubName: Nama hub tugas tempat orkestrasi Anda berjalan.
- appName: Nama aplikasi fungsi. Bidang ini berguna saat Anda memiliki beberapa aplikasi fungsi yang berbagi instans Application Insights yang sama.
- slotName: Slot penyebaran tempat aplikasi fungsi saat ini berjalan. Bidang ini berguna saat Anda menggunakan slot penyebaran untuk membuat versi orkestrasi Anda.
- functionName: Nama orkestrator atau fungsi aktivitas.
- functionType: Jenis fungsi, seperti Orkestrator atau Aktivitas.
- instanceId: ID unik dari instans orkestrasi.
- status: Status eksekusi siklus hidup instans. Nilai yang valid meliputi:
- Dijadwalkan: Fungsi ini dijadwalkan untuk eksekusi tetapi belum mulai berjalan.
- Dimulai: Fungsi sudah mulai berjalan tetapi belum menunggu atau selesai.
- Ditunggu: Orkestrator telah menjadwalkan beberapa pekerjaan dan menunggunya selesai.
- Mendengarkan: Orkestrator mendengarkan notifikasi kejadian eksternal.
- Selesai: Fungsi telah berhasil diselesaikan.
- Gagal: Fungsi gagal dengan kesalahan.
- alasan: Data tambahan yang terkait dengan peristiwa pelacakan. Misalnya, jika instans sedang menunggu notifikasi kejadian eksternal, bidang ini menunjukkan nama peristiwa yang ditunggu. Jika fungsi gagal, bidang ini akan berisi detail kesalahan.
- isReplay: Nilai Boolean yang menunjukkan apakah peristiwa pelacakan adalah untuk eksekusi diputar ulang.
- extensionVersion: Versi ekstensi Tugas Durable. Informasi versi adalah data yang sangat penting saat melaporkan kemungkinan bug dalam ekstensi. Instans yang berjalan lama dapat melaporkan beberapa versi jika pembaruan terjadi saat dijalankan.
- sequenceNumber: Nomor urutan eksekusi untuk suatu peristiwa. Dikombinasikan dengan tanda waktu membantu mengurutkan peristiwa berdasarkan waktu eksekusi. Perhatikan bahwa nomor ini akan diatur ulang ke nol jika host dimulai ulang saat instans berjalan, jadi penting untuk selalu mengurutkan berdasarkan tanda waktu terlebih dahulu, lalu sequenceNumber.
Verbositas pelacakan data yang dipancarkan ke Application Insights dapat dikonfigurasi di bagian logger
(Functions 1.x) ata logging
(Functions 2.0) file host.json
.
Functions 1.0
{
"logger": {
"categoryFilter": {
"categoryLevels": {
"Host.Triggers.DurableTask": "Information"
}
}
}
}
Functions 2.0
{
"logging": {
"logLevel": {
"Host.Triggers.DurableTask": "Information",
},
}
}
Secara default, semua peristiwa pelacakan non-pemutaran ulang dihilangkan. Volume data dapat dikurangi dengan mengatur Host.Triggers.DurableTask
ke "Warning"
atau "Error"
, dalam hal ini peristiwa pelacakan hanya akan dipancarkan untuk situasi yang luar biasa. Untuk mengaktifkan pemancaran peristiwa pemutaran ulang orkestrasi verbose, atur logReplayEvents
ke true
dalam file konfigurasi host.json.
Catatan
Secara default, telemetri Application Insights dicontohkan oleh runtime Azure Functions untuk menghindari pemancaran data terlalu sering. Hal ini dapat menyebabkan informasi pelacakan hilang ketika banyak peristiwa siklus hidup terjadi dalam waktu singkat. Artikel Pemantauan Azure Functions menjelaskan cara mengonfigurasi perilaku ini.
Input dan output dari orkestra, aktivitas, dan fungsi entitas tidak dicatat secara default. Perilaku default ini disarankan karena pengelogan input dan output dapat meningkatkan biaya Application Insights. Payload input dan output fungsi juga dapat berisi informasi sensitif. Sebagai gantinya, jumlah byte untuk input dan output fungsi dicatat sebagai ganti payload aktual secara default. Jika Anda ingin ekstensi Durable Functions mencatat payload input dan output penuh, atur properti traceInputsAndOutputs
ke true
di file konfigurasi host.json.
Kueri instans tunggal
Kueri berikut menunjukkan data pelacakan historis untuk satu instans dari orkestrasi fungsi Hello Sequence. Ditulis menggunakan Bahasa Kueri Kusto. Kueri ini memfilter eksekusi pemutaran ulang sehingga hanya jalur eksekusi logis yang ditampilkan. Peristiwa dapat diurutkan berdasarkan timestamp
dan sequenceNumber
seperti yang ditampilkan dalam kueri di bawah ini:
let targetInstanceId = "ddd1aaa685034059b545eb004b15d4eb";
let start = datetime(2018-03-25T09:20:00);
traces
| where timestamp > start and timestamp < start + 30m
| where customDimensions.Category == "Host.Triggers.DurableTask"
| extend functionName = customDimensions["prop__functionName"]
| extend instanceId = customDimensions["prop__instanceId"]
| extend state = customDimensions["prop__state"]
| extend isReplay = tobool(tolower(customDimensions["prop__isReplay"]))
| extend sequenceNumber = tolong(customDimensions["prop__sequenceNumber"])
| where isReplay != true
| where instanceId == targetInstanceId
| sort by timestamp asc, sequenceNumber asc
| project timestamp, functionName, state, instanceId, sequenceNumber, appName = cloud_RoleName
Hasilnya adalah daftar peristiwa pelacakan yang menunjukkan jalur eksekusi orkestrasi, termasuk fungsi aktivitas apa pun yang diurutkan berdasarkan waktu eksekusi dalam urutan naik.
Kueri ringkasan instans
Kueri berikut menampilkan status semua instans orkestrasi yang dijalankan dalam rentang waktu yang ditentukan.
let start = datetime(2017-09-30T04:30:00);
traces
| where timestamp > start and timestamp < start + 1h
| where customDimensions.Category == "Host.Triggers.DurableTask"
| extend functionName = tostring(customDimensions["prop__functionName"])
| extend instanceId = tostring(customDimensions["prop__instanceId"])
| extend state = tostring(customDimensions["prop__state"])
| extend isReplay = tobool(tolower(customDimensions["prop__isReplay"]))
| extend output = tostring(customDimensions["prop__output"])
| where isReplay != true
| summarize arg_max(timestamp, *) by instanceId
| project timestamp, instanceId, functionName, state, output, appName = cloud_RoleName
| order by timestamp asc
Hasilnya adalah daftar ID instans dan status runtime mereka saat ini.
Pembuatan Log Kerangka Tugas Durable
Log ekstensi Durable berguna untuk memahami perilaku logika orkestrasi Anda. Namun, log ini tidak selalu berisi informasi yang cukup untuk men-debug masalah performa dan keandalan tingkat kerangka kerja. Mulai dari ekstensi Durable v2.3.0, log yang dipancarkan oleh Durable Task Framework (DTFx) yang mendasarinya juga tersedia untuk koleksi.
Ketika melihat log yang dikirimkan oleh DTFx, penting untuk dipahami bahwa mesin DTFx terdiri dari dua komponen: mesin pengiriman inti (DurableTask.Core
) dan salah satu dari banyak penyedia penyimpanan yang didukung (Durable Functions menggunakan DurableTask.AzureStorage
secara default tetapi opsi lainnya tersedia).
- DurableTask.Core: Eksekusi orkestrasi inti dan log penjadwalan tingkat rendah dan telemetri.
- DurableTask.AzureStorage: Log backend khusus untuk penyedia status Azure Storage. Log ini mencakup interaksi terperinci dengan antrean internal, blob, dan tabel penyimpanan yang digunakan untuk menyimpan dan mengambil status orkestrasi internal.
- DurableTask.Netherite: Log backend khusus untuk penyedia penyimpanan Netherite, jika diaktifkan.
- DurableTask.SqlServer: Log backend khusus untuk penyedia penyimpanan Microsoft SQL (MSSQL), jika diaktifkan.
Anda dapat mengaktifkan log ini dengan memperbarui bagian logging/logLevel
dari file host.json aplikasi fungsi Anda. Contoh berikut menunjukkan cara mengaktifkan log peringatan dan kesalahan dari DurableTask.Core
dan DurableTask.AzureStorage
:
{
"version": "2.0",
"logging": {
"logLevel": {
"DurableTask.AzureStorage": "Warning",
"DurableTask.Core": "Warning"
}
}
}
Jika Anda mengaktifkan Application Insights, log ini akan secara otomatis ditambahkan ke koleksi trace
. Anda dapat mencarinya dengan cara yang sama seperti Anda mencari log trace
lain menggunakan kueri Kusto.
Catatan
Untuk aplikasi produksi, disarankan agar Anda mengaktifkan DurableTask.Core
dan log penyedia penyimpanan yang sesuai (misalnya, DurableTask.AzureStorage
) menggunakan filter "Warning"
. Filter verbositas yang lebih tinggi, seperti "Information"
sangat berguna untuk men-debug masalah performa. Namun, peristiwa log ini bervolume tinggi dan dapat secara signifikan meningkatkan biaya penyimpanan data Application Insights.
Kueri Kusto berikut ini menunjukkan cara membuat kueri untuk log DTFx. Bagian terpenting dari kueri adalah where customerDimensions.Category startswith "DurableTask"
, karena kueri memfilter hasil untuk log dalam kategori DurableTask.Core
dan DurableTask.AzureStorage
.
traces
| where customDimensions.Category startswith "DurableTask"
| project
timestamp,
severityLevel,
Category = customDimensions.Category,
EventId = customDimensions.EventId,
message,
customDimensions
| order by timestamp asc
Hasilnya adalah sekumpulan log yang ditulis oleh penyedia log Kerangka Kerja Tugas Durable.
Untuk informasi selengkapnya tentang apa saja peristiwa log yang tersedia, lihat dokumentasi pembuatan log terstruktur Kerangka Tugas Durable di GitHub.
Pembuatan Log Aplikasi
Penting untuk mengingat perilaku pemutaran ulang orkestrator saat menulis log secara langsung dari fungsi orkestrator. Misalnya, pertimbangkan fungsi orkestrator berikut:
[FunctionName("FunctionChain")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
log.LogInformation("Calling F1.");
await context.CallActivityAsync("F1");
log.LogInformation("Calling F2.");
await context.CallActivityAsync("F2");
log.LogInformation("Calling F3");
await context.CallActivityAsync("F3");
log.LogInformation("Done!");
}
Data log yang dihasilkan akan terlihat seperti contoh output berikut:
Calling F1.
Calling F1.
Calling F2.
Calling F1.
Calling F2.
Calling F3.
Calling F1.
Calling F2.
Calling F3.
Done!
Catatan
Ingat bahwa sementara log mengklaim akan memanggil F1, F2, dan F3, fungsi-fungsi tersebut hanya benar-benar dipanggil pada saat pertama kali mereka terjadi. Panggilan berikutnya yang terjadi selama pemutaran ulang dilewati dan output diputar ulang untuk logika orkestrator.
Jika Anda hanya ingin menulis log pada eksekusi non-pemutaran ulang, Anda dapat menulis ungkapan bersyarat untuk mencatat hanya jika bendera "sedang diputar ulang" adalah false
. Pertimbangkan contoh di atas, tetapi kali ini dengan pemeriksaan pemutaran ulang.
[FunctionName("FunctionChain")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
if (!context.IsReplaying) log.LogInformation("Calling F1.");
await context.CallActivityAsync("F1");
if (!context.IsReplaying) log.LogInformation("Calling F2.");
await context.CallActivityAsync("F2");
if (!context.IsReplaying) log.LogInformation("Calling F3");
await context.CallActivityAsync("F3");
log.LogInformation("Done!");
}
Mulai dari Durable Functions 2.0, fungsi orkestrator .NET juga memiliki opsi untuk membuat ILogger
yang secara otomatis memfilter pernyataan log selama pemutaran ulang. Pemfilteran otomatis ini dilakukan menggunakan API IDurableOrchestrationContext.CreateReplaySafeLogger(ILogger).
[FunctionName("FunctionChain")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
log = context.CreateReplaySafeLogger(log);
log.LogInformation("Calling F1.");
await context.CallActivityAsync("F1");
log.LogInformation("Calling F2.");
await context.CallActivityAsync("F2");
log.LogInformation("Calling F3");
await context.CallActivityAsync("F3");
log.LogInformation("Done!");
}
Catatan
Contoh C# sebelumnya adalah untuk Durable Functions 2.x. Untuk Durable Functions 1.x, Anda harus menggunakan DurableOrchestrationContext
dan bukan IDurableOrchestrationContext
. Untuk informasi selengkapnya tentang perbedaan antara versi, lihat artikel Versi Durable Functions.
Dengan perubahan yang disebutkan sebelumnya, output log adalah sebagai berikut:
Calling F1.
Calling F2.
Calling F3.
Done!
Status Kustom
Status orkestrasi kustom memungkinkan Anda menetapkan nilai status kustom untuk fungsi orkestrator Anda. Status kustom ini kemudian dapat dilihat oleh klien eksternal melalui API kueri status HTTP atau melalui panggilan API khusus bahasa. Status orkestrasi kustom memungkinkan pemantauan yang lebih beragam untuk fungsi orkestrator. Misalnya, kode fungsi orkestrator dapat memanggil API "atur status kustom" untuk memperbarui kemajuan operasi yang berjalan dalam jangka waktu lama. Klien, seperti halaman web atau sistem eksternal lainnya, kemudian dapat secara berkala mengkuerikan API kueri status HTTP untuk informasi kemajuan yang lebih beragam. Contoh kode untuk mengatur nilai status kustom dalam fungsi orkestrator tersedia di bawah ini:
[FunctionName("SetStatusTest")]
public static async Task SetStatusTest([OrchestrationTrigger] IDurableOrchestrationContext context)
{
// ...do work...
// update the status of the orchestration with some arbitrary data
var customStatus = new { completionPercentage = 90.0, status = "Updating database records" };
context.SetCustomStatus(customStatus);
// ...do more work...
}
Catatan
Contoh C# sebelumnya adalah untuk Durable Functions 2.x. Untuk Durable Functions 1.x, Anda harus menggunakan DurableOrchestrationContext
dan bukan IDurableOrchestrationContext
. Untuk informasi selengkapnya tentang perbedaan antara versi, lihat artikel Versi Durable Functions.
Saat orkestrasi berjalan, klien eksternal dapat mengambil status kustom ini:
GET /runtime/webhooks/durabletask/instances/instance123?code=XYZ
Klien akan mendapatkan respons berikut:
{
"runtimeStatus": "Running",
"input": null,
"customStatus": { "completionPercentage": 90.0, "status": "Updating database records" },
"output": null,
"createdTime": "2017-10-06T18:30:24Z",
"lastUpdatedTime": "2017-10-06T19:40:30Z"
}
Peringatan
Payload status khusus dibatasi hingga 16 KB teks JSON UTF-16 karena harus pas di kolom Azure Table Storage. Anda dapat menggunakan penyimpanan eksternal jika membutuhkan payload yang lebih besar.
Pelacakan Terdistribusi
Pelacakan Terdistribusi melacak permintaan dan menunjukkan bagaimana layanan yang berbeda berinteraksi satu sama lain. Dalam Durable Functions, ini juga berkorelasi orkestrasi dan aktivitas bersama-sama. Ini berguna untuk memahami berapa banyak langkah waktu orkestrasi relatif terhadap seluruh orkestrasi. Juga berguna untuk memahami di mana aplikasi mengalami masalah atau di mana pengecualian dilemparkan. Fitur ini didukung untuk semua bahasa dan penyedia penyimpanan.
Catatan
Pelacakan Terdistribusi V2 memerlukan Durable Functions v2.12.0 atau yang lebih besar. Selain itu, Pelacakan Terdistribusi V2 berada dalam status pratinjau dan oleh karena itu beberapa pola Durable Functions tidak diinstrumentasikan. Misalnya, operasi Entitas Tahan Lama tidak diinstrumentasikan dan jejak tidak akan muncul di Application Insights.
Menyiapkan Pelacakan Terdistribusi
Untuk menyiapkan pelacakan terdistribusi, harap perbarui host.json dan siapkan sumber daya Application Insights.
host.json
"durableTask": {
"tracing": {
"distributedTracingEnabled": true,
"Version": "V2"
}
}
Application Insights
Jika aplikasi Fungsi tidak dikonfigurasi dengan sumber daya Application Insights, konfigurasikan dengan mengikuti instruksi di sini.
Memeriksa jejak
Di sumber daya Application Insights, navigasikan ke Pencarian Transaksi. Dalam hasilnya, periksa Request
peristiwa dan Dependency
yang dimulai dengan awalan spesifik Durable Functions (misalnya orchestration:
, , activity:
dll.). Memilih salah satu peristiwa ini akan membuka bagan Gantt yang akan menampilkan jejak terdistribusi ujung ke ujung.
Pemecahan Masalah
Jika Anda tidak melihat jejak di Application Insights, pastikan untuk menunggu sekitar lima menit setelah menjalankan aplikasi untuk memastikan bahwa semua data disebarkan ke sumber daya Application Insights.
Awakutu
Azure Functions mendukung kode fungsi penelusuran kesalahan secara langsung, dan dukungan yang sama diteruskan ke Durable Functions, baik yang berjalan di Azure atau secara lokal. Namun, ada beberapa perilaku yang harus diperhatikan saat melakukan penelusuran kesalahan:
- Pemutaran ulang: Fungsi orkestrator secara berkala diputar ulang ketika input baru diterima. Perilaku ini berarti eksekusi logis tunggal dari fungsi orkestrator dapat menghasilkan titik henti yang sama beberapa kali, terutama jika diatur lebih awal dalam kode fungsi.
- Tunggu: Setiap kali
await
ditemui dalam fungsi orkestrator, ini menghasilkan kontrol kembali ke dispatcher Kerangka Tugas Durable. Jika ini adalah pertama kalinyaawait
khusus ditemui, tugas terkait tidak pernah dilanjutkan. Karena tugas tidak pernah dilanjutkan, melangkahi yang ditunggu (F10 di Visual Studio) menjadi tidak mungkin. Tindakan melangkahi hanya bekerja ketika tugas sedang diputar ulang. - Batas waktu olah pesan: Durable Functions secara internal menggunakan pesan antrean untuk mendorong eksekusi fungsi orkestrator, aktivitas, dan entitas. Dalam lingkungan multi-VM, menghentikan penelusuran kesalahan untuk jangka waktu yang lama dapat menyebabkan VM lain mengambil pesan, sehingga menghasilkan eksekusi duplikat. Perilaku ini juga ada untuk fungsi pemicu antrean reguler, tetapi ini penting untuk menunjukkan dalam konteks ini karena antrean adalah detail implementasi.
- Berhenti dan memulai: Pesan dalam Durable Functions bertahan di antara sesi debug. Jika Anda menghentikan penelusuran kesalahan dan mengakhiri proses host lokal saat durable function dijalankan, fungsi tersebut dapat dieksekusi kembali secara otomatis dalam sesi debug di masa mendatang. Perilaku ini dapat menjadi membingungkan ketika tidak diharapkan. Penggunaan hub tugas baru atau pembersihan konten hub tugas di antara sesi debug adalah salah satu teknik untuk menghindari perilaku ini.
Tip
Saat mengatur titik henti dalam fungsi orkestrator, jika Anda hanya ingin menghentikan eksekusi non-pemutaran ulang, Anda dapat mengatur titik henti bersyarat yang hanya menghentikan jika nilai "sedang diputar ulang" adalah false
.
Penyimpanan
Secara default, Durable Functions menyimpan status di Azure Storage. Perilaku ini berarti Anda dapat memeriksa status orkestrasi Anda menggunakan alat seperti Microsoft Azure Storage Explorer.
Ini berguna untuk penelusuran kesalahan karena Anda melihat dengan tepat apa status orkestrasi yang sedang berlangsung. Pesan dalam antrean juga dapat diperiksa untuk mempelajari pekerjaan apa yang tertunda (atau dalam beberapa kasus, terjebak).
Peringatan
Meskipun mudah untuk melihat riwayat eksekusi dalam penyimpanan tabel, hindari mengambil dependensi apa pun pada tabel ini. Ini dapat berubah seiring berkembangnya ekstensi Durable Functions.
Catatan
Penyedia penyimpanan lain dapat dikonfigurasi alih-alih penyedia Azure Storage default. Bergantung pada penyedia penyimpanan yang dikonfigurasi untuk aplikasi, Anda mungkin perlu menggunakan berbagai alat untuk memeriksa status yang mendasarinya. Untuk informasi selengkapnya, lihat dokumentasi Penyedia Penyimpanan Fungsi Tahan Lama.
Durable Functions Monitor
Durable Functions Monitor adalah alat grafis untuk memantau, mengelola, dan men-debug orkestrasi dan instans entitas. Ini tersedia sebagai ekstensi Visual Studio Code atau aplikasi mandiri. Informasi tentang penyetelan dan daftar fitur dapat ditemukan di Wiki ini.
Panduan pemecahan masalah Durable Functions
Untuk memecahkan masalah umum gejala seperti orkestrasi yang macet, gagal memulai, berjalan lambat, dll., lihat panduan pemecahan masalah ini.