A Durable Functions diagnosztikája az Azure-ban

A Durable Functions problémáinak diagnosztizálása többféleképpen is lehetséges. Ezek némelyike megegyezik a hagyományos függvényekre vonatkozó módszerekkel, mások pedig csak a Durable Functions függvényeihez használhatók.

Application Insights

Az Alkalmazás Elemzések a diagnosztikai és monitorozási műveletek ajánlott módja az Azure Functionsben. Ugyanez vonatkozik a Durable Functionsre is. Az Alkalmazás Elemzések függvényalkalmazásban való használatának áttekintéséhez tekintse meg az Azure Functions monitorozását.

Az Azure Functions Durable Extension olyan nyomkövetési eseményeket is bocsát ki, amelyek lehetővé teszik a vezénylések végpontok közötti végrehajtásának nyomon követését. Ezek a nyomon követési események az Azure Portal Application Elemzések Analytics eszközével találhatók és kérdezhetők le.

Adatok nyomon követése

A vezénylési példány minden életciklus-eseménye követési eseményt ír az Application Elemzések nyomkövetési gyűjteményéhez. Ez az esemény több mezővel rendelkező customDimensions hasznos adatokat tartalmaz. A mezőnevek mindegyike elő van állítva a következővel prop__: .

  • hubName: Annak a feladatközpontnak a neve, amelyben a vezénylések futnak.
  • appName: A függvényalkalmazás neve. Ez a mező akkor hasznos, ha több függvényalkalmazás is ugyanazt az alkalmazás-Elemzések-példányt használja.
  • slotName: Az az üzembehelyezési pont , amelyen az aktuális függvényalkalmazás fut. Ez a mező akkor hasznos, ha üzembehelyezési pontok használatával verziószámozza a vezényléseket.
  • functionName: A vezénylő vagy tevékenységfüggvény neve.
  • functionType: A függvény típusa, például Orchestrator vagy Activity.
  • instanceId: A vezénylési példány egyedi azonosítója.
  • állapot: A példány életciklus-végrehajtási állapota. Az érvényes értékek a következők:
    • Ütemezett: A függvény végrehajtásra lett ütemezve, de még nem indult el.
    • Elindítva: A függvény elindult, de még nem várt vagy fejeződött be.
    • Várva: A vezénylő tervezett néhány munkát, és várja, hogy befejeződjön.
    • Figyelés: A vezénylő egy külső eseményértesítést figyel.
    • Befejeződött: A függvény sikeresen befejeződött.
    • Sikertelen: A függvény hiba miatt meghiúsult.
  • ok: A nyomkövetési eseményhez társított további adatok. Ha például egy példány egy külső eseményértesítésre vár, ez a mező annak az eseménynek a nevét jelzi, amelyre vár. Ha egy függvény sikertelen volt, ez a mező tartalmazza a hiba részleteit.
  • isReplay: Logikai érték, amely azt jelzi, hogy a nyomkövetési esemény az újrajátszott végrehajtáshoz tartozik-e.
  • extensionVersion: A Durable Task bővítmény verziója. A verzióinformációk különösen fontos adatok a bővítmény lehetséges hibáinak jelentésekor. A hosszan futó példányok több verziót is jelenthetnek, ha egy frissítés fut.
  • sequenceNumber: Egy esemény végrehajtási sorszáma. Az időbélyeggel kombinálva a végrehajtási idő alapján rendezheti az eseményeket. Vegye figyelembe, hogy ez a szám nullára lesz visszaállítva, ha a gazdagép újraindul a példány futása közben, ezért fontos, hogy mindig időbélyeg szerint rendezze először, majd a sequenceNumber függvényt.

Az Application Elemzések számára kibocsátott nyomkövetési adatok részletessége a fájl (Functions 1.x) vagy logging (Functions 2.0) szakaszában host.json konfigurálható logger .

Functions 1.0

{
    "logger": {
        "categoryFilter": {
            "categoryLevels": {
                "Host.Triggers.DurableTask": "Information"
            }
        }
    }
}

Functions 2.0

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

Alapértelmezés szerint minden nem visszajátszáskövetési esemény ki lesz bocsátva. Az adatok mennyisége csökkenthető úgy, hogy beállítja Host.Triggers.DurableTask vagy "Warning""Error" ebben az esetben a nyomon követési események csak kivételes helyzetekben lesznek kibocsátva. A részletes vezénylési újrajátszási események kibocsátásához állítsa be a logReplayEventstrue beállítást a host.json konfigurációs fájlban.

Feljegyzés

Alapértelmezés szerint az Azure Functions-futtatókörnyezet mintavételezi az alkalmazás Elemzések telemetriát, hogy elkerülje az adatok túl gyakran történő kibocsájtását. Ez azt okozhatja, hogy a nyomon követési adatok elvesznek, ha rövid időn belül számos életciklus-esemény történik. Az Azure Functions Monitorozási cikk bemutatja, hogyan konfigurálhatja ezt a viselkedést.

A vezénylő, tevékenység és entitásfüggvények bemeneteit és kimeneteit alapértelmezés szerint nem naplózza a rendszer. Ez az alapértelmezett viselkedés azért ajánlott, mert a bemenetek és kimenetek naplózása növelheti az alkalmazás Elemzések költségeit. A függvénybemenet és a kimeneti hasznos adatok bizalmas információkat is tartalmazhatnak. Ehelyett alapértelmezés szerint a függvénybemenetek és -kimenetek bájtjainak száma lesz naplózva a tényleges hasznos adatok helyett. Ha azt szeretné, hogy a Durable Functions bővítmény naplózza a teljes bemeneti és kimeneti hasznos adatokat, állítsa be a traceInputsAndOutputs tulajdonságot true a host.json konfigurációs fájlba.

Egypéldányos lekérdezés

Az alábbi lekérdezés a Hello Sequence függvény vezénylésének egyetlen példányára vonatkozó előzménykövetési adatokat mutatja be. A Kusto lekérdezésnyelv íródott. Kiszűri a visszajátszás végrehajtását, így csak a logikai végrehajtási útvonal jelenik meg. Az események rendezhetők az alábbi lekérdezés szerint timestamp és sequenceNumber módon:

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

Az eredmény azoknak a nyomon követési eseményeknek a listája, amelyek a vezénylés végrehajtási útvonalát jelenítik meg, beleértve a végrehajtási idő által növekvő sorrendben rendezett tevékenységfüggvényeket is.

Alkalmazás Elemzések egypéldányos rendezett lekérdezés

Példányösszegző lekérdezés

Az alábbi lekérdezés megjeleníti a megadott időtartományban futtatott vezénylési példányok állapotát.

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

Az eredmény a példányazonosítók listája és az aktuális futtatókörnyezeti állapotuk.

Alkalmazás Elemzések egypéldányos lekérdezés

Tartós feladat-keretrendszer naplózása

A Durable bővítménynaplók hasznosak a vezénylési logika viselkedésének megértéséhez. Ezek a naplók azonban nem mindig tartalmaznak elegendő információt a keretrendszerszintű teljesítmény- és megbízhatósági problémák hibakereséséhez. A Durable bővítmény 2.3.0-s verziójától kezdve a mögöttes Durable Task Framework (DTFx) által kibocsátott naplók is elérhetők a gyűjteményhez.

A DTFx által kibocsátott naplók megtekintésekor fontos tisztában lenni azzal, hogy a DTFx motor két összetevőből áll: az alapvető diszpécsermotorból (DurableTask.Core) és a számos támogatott tárolószolgáltató közül (a Durable Functions alapértelmezés szerint használja DurableTask.AzureStorage , de más lehetőségek is rendelkezésre állnak).

  • DurableTask.Core: Alapvető vezénylési végrehajtás és alacsony szintű ütemezési naplók és telemetriai adatok.
  • DurableTask.AzureStorage: Az Azure Storage-állapotszolgáltatóra jellemző háttérnaplók. Ezek a naplók részletes interakciókat tartalmaznak a belső üzenetsorokkal, blobokkal és tárolótáblákkal a belső vezénylési állapot tárolásához és lekéréséhez.
  • DurableTask.Netherite: Ha engedélyezve van, a Netherite-tárolószolgáltatóra vonatkozó háttérnaplók.
  • DurableTask.SqlServer: Ha engedélyezve van, a Microsoft SQL (MSSQL) tárolószolgáltatójának háttérnaplói.

Ezeket a naplókat a függvényalkalmazás host.json fájljának szakaszának frissítésével logging/logLevel engedélyezheti. Az alábbi példa bemutatja, hogyan engedélyezheti a figyelmeztetési és hibanaplókat mind a kettőbőlDurableTask.Core:DurableTask.AzureStorage

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

Ha engedélyezve van az Alkalmazás Elemzések, a rendszer automatikusan hozzáadja ezeket a naplókat a trace gyűjteményhez. Ugyanúgy kereshet bennük, mint más naplókban trace a Kusto-lekérdezések használatával.

Feljegyzés

Éles alkalmazások esetén ajánlott engedélyezni DurableTask.Core , és a megfelelő tárolószolgáltató (például DurableTask.AzureStorage) naplóit a "Warning" szűrő használatával. A nagyobb részletességű szűrők, például "Information" nagyon hasznosak a teljesítményproblémák hibakereséséhez. Ezek a naplóesemények azonban nagy mennyiségűek lehetnek, és jelentősen növelhetik az alkalmazás Elemzések adattárolás költségeit.

Az alábbi Kusto-lekérdezés bemutatja, hogyan kérdezhet le DTFx-naplókat. A lekérdezés legfontosabb része az, where customerDimensions.Category startswith "DurableTask" hogy szűri az eredményeket a naplókba és DurableTask.AzureStorage a DurableTask.Core kategóriákba.

traces
| where customDimensions.Category startswith "DurableTask"
| project
    timestamp,
    severityLevel,
    Category = customDimensions.Category,
    EventId = customDimensions.EventId,
    message,
    customDimensions
| order by timestamp asc 

Az eredmény a Durable Task Framework naplószolgáltatói által írt naplók halmaza.

Alkalmazás Elemzések DTFx-lekérdezés eredményei

A naplóeseményekről további információt a Durable Task Framework strukturált naplózási dokumentációjában talál a GitHubon.

Alkalmazásnaplózás

Fontos szem előtt tartani a vezénylő visszajátszási viselkedését, amikor naplókat ír közvetlenül egy vezénylő függvényből. Vegyük például a következő vezénylő függvényt:

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

Az eredményként kapott naplóadatok a következő példakimenethez hasonlóan fognak kinézni:

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

Feljegyzés

Ne feledje, hogy bár a naplók F1, F2 és F3 hívásra hivatkoznak, ezek a függvények csak akkor lesznek ténylegesen meghívva, amikor először találkoznak. A rendszer kihagyja a visszajátszás során felmerülő további hívásokat, és a kimeneteket visszajátssza a vezénylő logikába.

Ha csak nem visszajátszásos végrehajtásokra szeretne naplókat írni, akkor csak akkor írhat feltételes kifejezést a naplóhoz, ha az "ismétlés" jelzője .false Vegyük a fenti példát, de ezúttal visszajátszási ellenőrzésekkel.

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

A Durable Functions 2.0-tól kezdve a .NET vezénylő függvények is létrehozhatnak egy ILogger olyan parancsot, amely automatikusan kiszűri a naplókivonatokat a visszajátszás során. Ez az automatikus szűrés az IDurableOrchestrationContext.CreateReplay Széf Logger(ILogger) API használatával történik.

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

Feljegyzés

Az előző C#-példák a Durable Functions 2.x-hez tartoznak. A Durable Functions 1.x esetén a helyett IDurableOrchestrationContexta DurableOrchestrationContext . A verziók közötti különbségekről további információt a Durable Functions verzióiról szóló cikkben talál.

A korábban említett módosítások esetén a napló kimenete a következő:

Calling F1.
Calling F2.
Calling F3.
Done!

Egyéni állapot

Az egyéni vezénylési állapot lehetővé teszi egyéni állapotérték beállítását a vezénylő függvényhez. Ez az egyéni állapot ezután látható a külső ügyfelek számára a HTTP-állapot lekérdezési API-val vagy nyelvspecifikus API-hívásokkal. Az egyéni vezénylési állapot lehetővé teszi a vezénylő függvények részletesebb monitorozását. A vezénylő függvénykódja például meghívhatja az "egyéni állapot beállítása" API-t egy hosszú ideig futó művelet előrehaladásának frissítéséhez. Egy ügyfél, például egy weblap vagy más külső rendszer, ezt követően rendszeres időközönként lekérdezheti a HTTP állapot lekérdezési API-jait a részletesebb előrehaladási információk érdekében. A vezénylőfüggvények egyéni állapotértékének beállítására szolgáló mintakódot az alábbiakban találja:

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

Feljegyzés

Az előző C# példa a Durable Functions 2.x-hez készült. A Durable Functions 1.x esetén a helyett IDurableOrchestrationContexta DurableOrchestrationContext . A verziók közötti különbségekről további információt a Durable Functions verzióiról szóló cikkben talál.

Amíg a vezénylés fut, a külső ügyfelek lekérhetik ezt az egyéni állapotot:

GET /runtime/webhooks/durabletask/instances/instance123?code=XYZ

Az ügyfelek a következő választ kapják:

{
  "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"
}

Figyelmeztetés

Az egyéni állapot hasznos adatai legfeljebb 16 KB UTF-16 JSON-szövegre korlátozódnak, mert el kell férnie egy Azure Table Storage-oszlopban. Ha nagyobb hasznos adatra van szüksége, külső tárolót is használhat.

Elosztott nyomkövetés

Az elosztott nyomkövetés nyomon követi a kéréseket, és bemutatja, hogy a különböző szolgáltatások hogyan kommunikálnak egymással. A Durable Functionsben a vezényléseket és a tevékenységeket is korrelálja. Ez hasznos annak megértéséhez, hogy a vezénylés mennyi időt vesz igénybe a teljes vezényléshez képest. Az is hasznos, ha tisztában van azzal, hogy egy alkalmazás hol tapasztal problémát, vagy hol történt kivétel. Ez a funkció minden nyelvhez és társzolgáltatóhoz támogatott.

Feljegyzés

Az elosztott nyomkövetési V2-hez a Durable Functions 2.12.0-s vagy újabb verziójára van szükség. Az elosztott nyomkövetési V2 is előzetes verziójú, ezért egyes Durable Functions-minták nem lettek kialakítva. A Durable Entities-műveletek például nem rendszerezettek, és a nyomkövetések nem jelennek meg az Alkalmazás Elemzések.

Elosztott nyomkövetés beállítása

Az elosztott nyomkövetés beállításához frissítse a host.json, és állítson be egy alkalmazás-Elemzések erőforrást.

host.json

"durableTask": {
  "tracing": {
    "distributedTracingEnabled": true,
    "Version": "V2"
  }
}

Application Insights

Ha a függvényalkalmazás nincs alkalmazás Elemzések erőforrással konfigurálva, akkor az itt leírt utasításokat követve konfigurálja.

A nyomok vizsgálata

Az Alkalmazás Elemzések erőforrásban lépjen a Tranzakciókeresés elemre. Az eredményekben ellenőrizze RequestDependency a Durable Functions-specifikus előtagokkal (pl. orchestration:, activity:stb.) kezdődő eseményeket. Ha kiválaszt egy ilyen eseményt, megnyit egy Gantt-diagramot, amely a végpontok közötti elosztott nyomkövetést jeleníti meg.

Az alkalmazás Elemzések elosztott nyomkövetést megjelenítő Gantt-diagram.

Hibaelhárítás

Ha nem látja a nyomkövetéseket az Alkalmazás Elemzések, az alkalmazás futtatása után várjon körülbelül öt percet, hogy az összes adat propagálása az alkalmazás Elemzések erőforrásba történjen.

Hibakeresés

Az Azure Functions közvetlenül támogatja a függvénykód hibakeresését, és ugyanez a támogatás továbbviszi a Durable Functionst, akár az Azure-ban, akár helyileg fut. A hibakereséskor azonban érdemes néhány viselkedést figyelembe venni:

  • Visszajátszás: Az Orchestrator rendszeresen újrajátszja az új bemenetek fogadását. Ez a viselkedés azt jelenti, hogy egy vezénylőfüggvény egyetlen logikai végrehajtása ugyanazt a töréspontot többször is elérheti, különösen akkor, ha a függvénykód elején van beállítva.
  • Várjon: Amikor egy vezénylő függvényben talál egy await hibát, az visszaveti az irányítást a Durable Task Framework diszpécsernek. Ha ez az első alkalom, hogy egy adott await feladatba ütközik, a társított tevékenység soha nem folytatódik. Mivel a feladat soha nem folytatódik, nem lehet túllépni a várakozáson (F10 a Visual Studióban). Az átlépés csak akkor működik, ha egy feladat visszajátszása történik.
  • Üzenetküldési időtúllépések: A Durable Functions belsőleg üzenetsor-üzeneteket használ a vezénylő, a tevékenység és az entitásfüggvények végrehajtásának ösztönzésére. Több virtuálisgép-környezetben a hibakeresés hosszabb ideig történő betörésével egy másik virtuális gép is átveheti az üzenetet, ami duplikált végrehajtást eredményezhet. Ez a viselkedés a rendszeres üzenetsor-eseményindító függvények esetében is létezik, de ebben a kontextusban fontos kiemelni, mivel az üzenetsorok implementálási részletek.
  • Leállítás és indítás: A Durable függvényekben lévő üzenetek továbbra is megmaradnak a hibakeresési munkamenetek között. Ha leállítja a hibakeresést, és leállítja a helyi gazdagépfolyamatot egy tartós függvény végrehajtása közben, a függvény automatikusan újrafuthat egy későbbi hibakeresési munkamenetben. Ez a viselkedés zavaró lehet, ha nem várható. Ennek a viselkedésnek a elkerülése érdekében egy új tevékenységközpont használata vagy a feladatközpont tartalmának törlése a hibakeresési munkamenetek között.

Tipp.

Ha a vezénylő függvények töréspontjait állítja be, ha csak a nem visszajátszásos végrehajtást szeretné megszakítani, akkor beállíthat egy feltételes töréspontot, amely csak akkor törik meg, ha az "ismétlés" értéke .false

Tárolás

Alapértelmezés szerint a Durable Functions az Azure Storage-ban tárolja az állapotot. Ez a viselkedés azt jelenti, hogy az olyan eszközökkel, mint a Microsoft Azure Storage Explorer, megvizsgálhatja a vezénylések állapotát.

Az Azure Storage Explorer képernyőképe

Ez azért hasznos a hibakereséshez, mert pontosan láthatja, hogy milyen állapotban lehet egy vezénylés. Az üzenetsorokban lévő üzeneteket is megvizsgálhatja, hogy megtudja, mi a függőben lévő munka (vagy néhány esetben elakadt).

Figyelmeztetés

Bár kényelmesen megtekintheti a végrehajtási előzményeket a táblatárolóban, ne függjön a táblától. A Durable Functions bővítmény fejlődésével változhat.

Feljegyzés

Az alapértelmezett Azure Storage-szolgáltató helyett más tárolószolgáltatók is konfigurálhatók. Az alkalmazáshoz konfigurált tárolószolgáltatótól függően előfordulhat, hogy a mögöttes állapot vizsgálatához különböző eszközöket kell használnia. További információkért tekintse meg a Durable Functions Storage-szolgáltatók dokumentációját.

Durable Functions Monitor

A Durable Functions Monitor egy grafikus eszköz a vezénylési és entitáspéldányok monitorozására, kezelésére és hibakeresésére. Visual Studio Code-bővítményként vagy önálló alkalmazásként érhető el. A beállítással és a funkciók listájával kapcsolatos információk ebben a wikiben találhatók.

A Durable Functions hibaelhárítási útmutatója

Az olyan gyakori problémák elhárításához, mint a elakadt vezénylések, a sikertelen indítás, a lassú futás stb., tekintse meg ezt a hibaelhárítási útmutatót.

Következő lépések