Mendiagnosis dan memecahkan masalah dalam Durable Functions

Durable Functions menyediakan beberapa alat diagnostik untuk memecahkan masalah orkestrasi. Artikel ini membahas cara mengonfigurasi pelacakan dan pengelogan, menulis kode replay-safe, memeriksa jejak terdistribusi, dan men-debug secara lokal.

Dalam artikel ini, Anda akan mempelajari cara:

Mengonfigurasi pelacakan Application Insights

Application Insights adalah cara yang direkomendasikan untuk memantau Durable Functions. Ekstensi Durable mengeluarkan peristiwa pelacakan yang memungkinkan Anda melacak eksekusi end-to-end orkestrasi. Anda dapat menemukan dan mengkueri peristiwa pelacakan ini menggunakan alat Application Insights Analytics di portal Azure.

Konfigurasi tingkat log

Konfigurasikan verbositas data pelacakan yang dipancarkan ke Application Insights dalam file host.json Anda:

{
    "logging": {
        "logLevel": {
            "Host.Triggers.DurableTask": "Information",
        },
    }
}

Secara default, semua peristiwa pelacakan non-pemutaran ulang dipancarkan. Anda dapat mengurangi volume data dengan mengatur Host.Triggers.DurableTask ke "Warning" atau "Error", yang berarti peristiwa pelacakan hanya dipancarkan untuk situasi yang luar biasa. Untuk mengaktifkan pemancaran peristiwa rekaman ulang orkestrasi secara verbose, atur logReplayEvents ke true dalam file konfigurasi host.json.

Note

Secara bawaan, runtime Azure Functions secara otomatis mengambil sampel telemetri Application Insights untuk menghindari pengiriman data terlalu sering. Pengambilan sampel dapat menyebabkan informasi pelacakan hilang ketika banyak peristiwa siklus hidup terjadi dalam waktu singkat. Artikel Azure Functions Monitoring menjelaskan cara mengonfigurasi perilaku ini.

Pencatatan input dan output

Secara default, input dan output fungsi orkestrator, aktivitas, dan entitas tidak dicatat. Pendekatan ini direkomendasikan karena pencatatan log 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. Jika Anda ingin ekstensi Durable Functions mencatat payload input dan output lengkap, atur properti traceInputsAndOutputs ke true di file konfigurasi host.json.

Instans orkestrasi kueri

Gunakan kueri Kusto berikut di Application Insights Analytics untuk memeriksa instans orkestrasi.

Kueri instans tunggal

Kueri berikut menunjukkan data pelacakan historis untuk instance tunggal dari orkestrasi fungsi Hello Sequence. Ini memfilter eksekusi pemutaran ulang sehingga hanya jalur eksekusi logis yang ditampilkan. Anda bisa mengurutkan peristiwa dengan mengurutkan menurut timestamp dan sequenceNumber seperti yang diperlihatkan dalam kueri berikut:

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 oleh waktu eksekusi dalam urutan naik.

Cuplikan layar Application Insights memperlihatkan hasil kueri yang diurutkan instans tunggal dengan peristiwa pelacakan.

Kueri ringkasan contoh

Kueri berikut menampilkan status semua instans orkestrasi yang dijalankan dalam rentang waktu tertentu.

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 runtimenya saat ini.

Cuplikan layar Application Insights memperlihatkan hasil kueri ringkasan instans tunggal dengan ID instans dan status.

Referensi data pelacakan

Setiap instansi orkestrasi menghasilkan peristiwa pelacakan saat berjalan melalui siklus hidupnya. Setiap peristiwa siklus hidup berisi payload customDimensions dengan beberapa bidang. Nama bidang semuanya diawali dengan prop__.

Nama bidang Description
hubName ** Nama hub tugas di mana orkestrasi Anda berjalan.
appName Nama aplikasi fungsi. Bidang ini berguna ketika 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 Orchestrator atau Aktivitas.
instanceId ID unik orkestrasi instans.
state Status eksekusi siklus hidup instans.
state.Scheduled Fungsi ini dijadwalkan untuk eksekusi tetapi belum mulai berjalan.
state.Started Fungsi mulai berjalan tetapi belum menunggu atau selesai.
state.Awaited Orkestrator menjadwalkan beberapa pekerjaan dan menunggunya selesai.
state.Listening Orkestrator mendengarkan pemberitahuan peristiwa eksternal.
state.Completed Fungsi berhasil diselesaikan.
state.Failed Fungsi mengalami error.
reason Data tambahan yang terkait dengan peristiwa pelacakan. Misalnya, jika instans menunggu pemberitahuan peristiwa eksternal, bidang ini menunjukkan nama peristiwa yang ditunggu. Jika fungsi gagal, bidang ini berisi detail kesalahan.
isReplay Nilai Boolean yang menunjukkan apakah peristiwa pelacakan ditujukan untuk eksekusi ulang.
extensionVersion Versi Ekstensi Durable Task. Informasi versi adalah data yang sangat penting ketika melaporkan kemungkinan bug dalam ekstensi. Instans yang berjalan lama dapat melaporkan beberapa versi jika pembaruan terjadi saat instans berjalan.
sequenceNumber Nomor urutan eksekusi untuk suatu peristiwa. Dikombinasikan dengan tanda waktu, ini membantu mengurutkan peristiwa berdasarkan waktu eksekusi. Perhatikan bahwa angka ini diatur ulang ke nol jika host dijalankan kembali ketika instans berjalan, jadi penting untuk selalu mengurutkan berdasarkan penanda waktu terlebih dahulu, lalu sequenceNumber.

Pengelogan Kerangka Kerja Tugas Tahan Lama (DTFx)

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 dihasilkan oleh Durable Task Framework (DTFx) yang mendasar juga tersedia untuk pengumpulan.

Ketika melihat log yang dipancarkan oleh DTFx, penting untuk dipahami bahwa mesin DTFx memiliki dua komponen: mesin pengiriman inti (DurableTask.Core) dan salah satu dari banyak penyedia penyimpanan yang didukung.

Komponen Description
DurableTask.Core Eksekusi orkestrasi inti dan log penjadwalan serta telemetri tingkat rendah.
DurableTask.DurableTaskScheduler Log backend khusus untuk Durable Task Scheduler.
DurableTask.AzureStorage Log backend yang spesifik untuk penyedia status penyimpanan Azure. 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 file host.json aplikasi fungsi Anda. Contoh berikut menunjukkan cara mengaktifkan log peringatan dan kesalahan dari kedua DurableTask.Core dan DurableTask.AzureStorage:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.AzureStorage": "Warning",
      "DurableTask.Core": "Warning"
    }
  }
}

Jika Anda mengaktifkan Application Insights, log ini secara otomatis ditambahkan ke trace koleksi. Anda dapat mencarinya dengan cara yang sama seperti Anda mencari log lain trace menggunakan kueri Kusto.

Note

Untuk aplikasi produksi, kami merekomendasikan mengaktifkan log DurableTask.Core dan penyedia penyimpanan yang sesuai (misalnya, DurableTask.AzureStorage) dengan menggunakan filter "Warning". Filter verbositas yang lebih tinggi seperti "Information" berguna untuk men-debug masalah performa. Namun, peristiwa log ini dapat berupa volume tinggi dan dapat secara signifikan meningkatkan biaya penyimpanan data Application Insights.

Kueri Kusto berikut ini memperlihatkan cara mengkueri log DTFx. Bagian terpenting dari kueri adalah where customerDimensions.Category startswith "DurableTask" karena 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 Tahan Lama.

Cuplikan layar Application Insights memperlihatkan hasil kueri DTFx dengan log Durable Task Framework.

Untuk informasi selengkapnya tentang peristiwa log apa yang tersedia, lihat dokumentasi pengelogan terstruktur Durable Task Framework di GitHub.

Pelacakan terdistribusi

Pelacakan terdistribusi melacak permintaan dan menunjukkan bagaimana layanan yang berbeda berinteraksi satu sama lain. Dalam Durable Functions, mengaitkan orkestrasi, entitas, dan aktivitas bersama-sama. Pelacakan terdistribusi menunjukkan waktu eksekusi untuk setiap langkah orkestrasi relatif terhadap seluruh orkestrasi dan mengidentifikasi di mana masalah atau pengecualian terjadi. Fitur ini didukung dalam Application Insights untuk semua bahasa dan penyedia penyimpanan.

Prerequisites

Pelacakan terdistribusi memerlukan versi ekstensi minimum tertentu:

Menyiapkan pelacakan terdistribusi

Untuk mengonfigurasi pelacakan terdistribusi, perbarui host.json dan siapkan sumber daya Application Insights.

host.json

{
   "extensions": {
     "durableTask": {
       "tracing": {
         "distributedTracingEnabled": true,
         "version": "V2"
       }
     }
   }
 }

Application Insights

Konfigurasikan aplikasi fungsi Anda dengan sumber daya Application Insights.

Memeriksa jejak

Di sumber daya Application Insights Anda, navigasikan ke Pencarian Transaksi. Dalam hasilnya, cari peristiwa Request dan Dependency yang dimulai dengan awalan khusus "Durable" (misalnya, orchestration:, activity:, dll.). Memilih salah satu peristiwa ini membuka bagan Gantt yang memperlihatkan jejak yang terdistribusi ujung ke ujung. Bagan menampilkan setiap langkah orkestrasi sebagai bilah horizontal, dengan aktivitas dan panggilan sub-orkestrasi yang disarangkan di bawah orkestrasi induknya. Panjang batang mewakili durasi jam dinding dari setiap langkah, sehingga memudahkan untuk menemukan hambatan atau aktivitas yang tidak terduga lambat.

Cuplikan layar bagan Gantt memperlihatkan jejak terdistribusi Application Insights dengan orkestrasi dan garis waktu aktivitas.

Note

Tidak melihat jejak Anda di Application Insights? Tunggu sekitar lima menit setelah menjalankan aplikasi Anda untuk memastikan bahwa semua data disebarluaskan ke sumber daya Application Insights.

Pencatatan yang aman dari pengulangan dalam fungsi orkestrator

Fungsi orkestrator diputar ulang setiap kali input baru diterima, yang berarti setiap pernyataan log dalam orkestrator berjalan beberapa kali untuk satu eksekusi logis. Misalnya, fungsi dengan tiga panggilan aktivitas menghasilkan output log seperti ini selama pemutaran ulang:

Calling F1.
Calling F1.
Calling F2.
Calling F1.
Calling F2.
Calling F3.
Calling F1.
Calling F2.
Calling F3.
Done!

Untuk mencegah duplikasi baris log, periksa indikator "sedang diputar ulang" agar log hanya dieksekusi pada lintasan pertama (tanpa pemutaran ulang). Contoh berikut menunjukkan log pemutaran ulang yang aman dalam setiap bahasa.

Mulai dari Durable Functions 2.0, gunakan CreateReplaySafeLogger untuk memfilter pernyataan log secara otomatis selama pemutaran ulang:

[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!");
}

Dengan pengelogan yang aman untuk pemutaran ulang, output log adalah:

Calling F1.
Calling F2.
Calling F3.
Done!

Status orkestrasi khusus

Gunakan status orkestrasi kustom untuk melaporkan kemajuan alur kerja ke klien eksternal. Pola umum termasuk persentase penyelesaian, deskripsi langkah, dan ringkasan kesalahan. Klien eksternal dapat melihat status kustom melalui API kueri status HTTP atau panggilan API khusus bahasa.

Kode berikut menunjukkan cara mengatur nilai status kustom dalam fungsi orkestrator:

[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...
}

Note

Contoh C# sebelumnya adalah untuk Durable Functions 2.x. Untuk Durable Functions 1.x, Anda harus menggunakan DurableOrchestrationContext alih-alih IDurableOrchestrationContext. Untuk informasi selengkapnya tentang perbedaan antar 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 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"
}

Warning

Payload status kustom dibatasi hingga 16 KB teks JSON UTF-16 karena perlu pas dalam kolom Penyimpanan Tabel Azure. Anda dapat menggunakan penyimpanan eksternal jika Anda memerlukan payload yang lebih besar.

Debugging

Azure Functions mendukung debugging kode fungsi secara langsung, dan dukungan yang sama tersebut diteruskan ke Durable Functions, baik berjalan di Azure atau secara lokal. Gunakan alur kerja berikut untuk pengalaman penelusuran kesalahan terbaik:

  1. Mulai sesi debug baru dengan hub tugas baru atau hapus konten hub tugas antar sesi. Pesan yang tersisa dari eksekusi sebelumnya dapat menyebabkan eksekusi ulang secara tidak terduga.

  2. Atur titik henti di orkestrator atau fungsi aktivitas Anda. Untuk fungsi orkestrator, gunakan titik henti bersyarat yang hanya rusak ketika nilai "sedang diputar ulang" adalah false untuk menghindari mencapai titik henti yang sama beberapa kali selama pemutaran ulang.

  3. Melangkah melalui kode Anda seperti biasa. Perlu diingat perilaku berikut:

    • Replay:
      Fungsi orkestrator secara teratur dijalankan kembali ketika input baru diterima. Satu eksekusi logis fungsi orkestrator dapat mengakibatkan mencapai titik henti yang sama beberapa kali, terutama jika diatur awal dalam kode fungsi.

    • Menunggu:
      Ketika await ditemui dalam fungsi orkestrator, kontrol diberikan kembali ke dispatcher Durable Task Framework. Jika ini pertama kalinya await ditemui, tugas terkait tidak pernah dilanjutkan. Karena tugas tidak pernah dilanjutkan, melangkahi proses menunggu (F10 dalam Visual Studio) tidak dimungkinkan. Melangkahi hanya berfungsi ketika tugas sedang diputar ulang.

    • Waktu habis pesan:
      Durable Functions secara internal menggunakan pesan antrean untuk menggerakkan eksekusi fungsi orkestrator, aktivitas, dan entitas. Dalam lingkungan multi-VM, sesi penelusuran kesalahan yang diperpanjang dapat menyebabkan VM lain memproses pesan, yang mengakibatkan eksekusi duplikat. Meskipun perilaku ini juga ada untuk fungsi pemicu antrean reguler, konteks ini penting untuk disorot karena antrean adalah detail implementasi.

    • Menghentikan dan memulai:
      Pesan dalam Durable Functions bertahan di antara sesi debug. Jika Anda berhenti men-debug dan mengakhiri proses host lokal saat fungsi tahan lama sedang dieksekusi, fungsi tersebut mungkin akan dieksekusi kembali secara otomatis dalam sesi debug berikutnya di masa mendatang.

Alat tambahan

Memeriksa status penyimpanan

Secara default, Durable Functions menyimpan status di Azure Storage. Anda dapat memeriksa status orkestrasi dan pesan menggunakan alat seperti Microsoft Azure Storage Explorer.

Screenshot Azure Storage Explorer menunjukkan status orchestrasi Durable Functions dalam tabel dan antrean.

Warning

Meskipun lebih mudah untuk melihat riwayat eksekusi dalam penyimpanan tabel, hindari mengambil dependensi apa pun pada tabel ini. Ini mungkin berubah seiring berkembangnya ekstensi Durable Functions.

Note

Anda dapat mengonfigurasi penyedia penyimpanan lain alih-alih penyedia Azure Storage default. Bergantung pada penyedia penyimpanan yang dikonfigurasi untuk aplikasi, Anda mungkin perlu menggunakan alat yang berbeda untuk memeriksa status yang mendasar.

Monitor Fungsi Tahan Lama

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. Untuk instruksi penyiapan dan daftar fitur, lihat Durable Functions Monitor Wiki.

Diagnostik Azure Portal

Portal Azure menyediakan alat diagnostik bawaan untuk aplikasi fungsi Anda.

Mendiagnosis dan memecahkan masalah: Azure Function App Diagnostics adalah sumber daya yang berguna untuk memantau dan mendiagnosis potensi masalah dalam aplikasi Anda. Ini juga memberikan saran untuk membantu menyelesaikan masalah berdasarkan diagnosis. Untuk informasi selengkapnya, lihat Azure Function App Diagnostics.

Jejak orkestrasi: Portal Microsoft Azure menyediakan detail jejak orkestrasi untuk membantu Anda memahami status setiap instans orkestrasi dan melacak eksekusi end-to-end. Saat Melihat daftar fungsi di dalam aplikasi Azure Functions, Anda akan melihat kolom Monitor yang berisi tautan ke jejak. Anda harus mengaktifkan Application Insights agar aplikasi Anda dapat mengakses informasi ini.

Roslyn Analyzer (Alat Analisis Roslyn)

Durable Functions Roslyn Analyzer adalah penganalisis kode langsung yang memandu pengembang C# untuk mengikuti batasan kode spesifik dari Durable Functions. Untuk petunjuk tentang cara mengaktifkannya di Visual Studio dan Visual Studio Code, lihat Durable Functions Roslyn Analyzer.

Troubleshooting

Untuk memecahkan masalah umum seperti orkestrasi yang macet, gagal memulai, atau berjalan lambat, lihat panduan pemecahan masalah Durable Functions.

Langkah berikutnya