Monitorování a ladění aplikace Azure Batch .NET pomocí Application Insights

Application Insights poskytuje vývojářům elegantní a výkonný způsob, jak monitorovat a ladit aplikace nasazené do služeb Azure. Pomocí Application Insights můžete monitorovat čítače výkonu a výjimky a také instrumentovat kód pomocí vlastních metrik a trasování. Integrace Application Insights s Azure Batch aplikací vám umožní získat podrobné přehledy o chování a zkoumat problémy téměř v reálném čase.

Tento článek popisuje, jak do řešení Azure Batch .NET přidat a nakonfigurovat knihovnu Application Insights a jak instrumentovat kód aplikace. Ukazuje také způsoby, jak monitorovat aplikaci prostřednictvím Azure Portal a vytvářet vlastní řídicí panely. Informace o podpoře Application Insights v jiných jazycích najdete v dokumentaci k jazykům, platformám a integracím.

Ukázkové řešení jazyka C# s kódem, který doprovází tento článek, je k dispozici na GitHubu. Tento příklad přidá do příkladu TopNWords instrumentační kód Application Insights. Pokud tento příklad neznáte, zkuste nejprve sestavit a spustit TopNWords. Pomůže vám to porozumět základnímu pracovnímu postupu služby Batch při paralelním zpracování sady vstupních objektů blob na více výpočetních uzlech.

Tip

Alternativně nakonfigurujte řešení Batch tak, aby se v Batch Exploreru zobrazovala data Application Insights, jako jsou čítače výkonu virtuálních počítačů. Batch Explorer je bezplatný samostatný klientský nástroj s bohatými funkcemi, který vám pomůže vytvářet, ladit a monitorovat Azure Batch aplikace. Můžete si stáhnout instalační balíček pro Mac, Linux nebo Windows. Rychlé kroky k povolení dat Application Insights v Batch Exploreru najdete v úložišti batch-insights .

Požadavky

Přidání Application Insights do projektu

Pro váš projekt se vyžaduje balíček NuGet Microsoft.ApplicationInsights.WindowsServer a jeho závislosti. Přidejte je do projektu aplikace nebo je obnovte. K instalaci balíčku použijte Install-Package příkaz nebo Správce balíčků NuGet.

Install-Package Microsoft.ApplicationInsights.WindowsServer

Odkazujte na Application Insights z aplikace .NET pomocí oboru názvů Microsoft.ApplicationInsights .

Instrumentace kódu

K instrumentaci kódu potřebuje vaše řešení vytvořit TelemetryClient pro Application Insights. V tomto příkladu TelemetryClient načte svou konfiguraci ze souboru ApplicationInsights.config . Nezapomeňte aktualizovat ApplicationInsights.config v následujících projektech pomocí instrumentačního klíče Application Insights: Microsoft.Azure.Batch.Samples.TelemetryStartTask a TopNWordsSample.

<InstrumentationKey>YOUR-IKEY-GOES-HERE</InstrumentationKey>

Přidejte také instrumentační klíč do souboru TopNWords.cs.

Příklad v souboru TopNWords.cs používá následující volání instrumentace z rozhraní API Application Insights:

  • TrackMetric() – Sleduje, jak dlouho v průměru trvá výpočetnímu uzlu stažení požadovaného textového souboru.
  • TrackTrace() – Přidá volání ladění do kódu.
  • TrackEvent() - Sleduje zajímavé události k zachycení.

Tento příklad záměrně vynechá zpracování výjimek. Místo toho Application Insights automaticky hlásí neošetřené výjimky, což výrazně zlepšuje prostředí ladění.

Následující fragment kódu ukazuje, jak tyto metody používat.

public void CountWords(string blobName, int numTopN, string storageAccountName, string storageAccountKey)
{
    // simulate exception for some set of tasks
    Random rand = new Random();
    if (rand.Next(0, 10) % 10 == 0)
    {
        blobName += ".badUrl";
    }

    // log the url we are downloading the file from
    insightsClient.TrackTrace(new TraceTelemetry(string.Format("Task {0}: Download file from: {1}", this.taskId, blobName), SeverityLevel.Verbose));

    // open the cloud blob that contains the book
    var storageCred = new StorageCredentials(storageAccountName, storageAccountKey);
    CloudBlockBlob blob = new CloudBlockBlob(new Uri(blobName), storageCred);
    using (Stream memoryStream = new MemoryStream())
    {
        // calculate blob download time
        DateTime start = DateTime.Now;
        blob.DownloadToStream(memoryStream);
        TimeSpan downloadTime = DateTime.Now.Subtract(start);

        // track how long the blob takes to download on this node
        // this will help debug timing issues or identify poorly performing nodes
        insightsClient.TrackMetric("Blob download in seconds", downloadTime.TotalSeconds, this.CommonProperties);

        memoryStream.Position = 0; //Reset the stream
        var sr = new StreamReader(memoryStream);
        var myStr = sr.ReadToEnd();
        string[] words = myStr.Split(' ');

        // log how many words were found in the text file
        insightsClient.TrackTrace(new TraceTelemetry(string.Format("Task {0}: Found {1} words", this.taskId, words.Length), SeverityLevel.Verbose));
        var topNWords =
            words.
                Where(word => word.Length > 0).
                GroupBy(word => word, (key, group) => new KeyValuePair<String, long>(key, group.LongCount())).
                OrderByDescending(x => x.Value).
                Take(numTopN).
                ToList();
        foreach (var pair in topNWords)
        {
            Console.WriteLine("{0} {1}", pair.Key, pair.Value);
        }

        // emit an event to track the completion of the task
        insightsClient.TrackEvent("Done counting words");
    }
}

Pomocník inicializátoru telemetrie Azure Batch

Při generování sestav telemetrie pro daný server a instanci Application Insights jako výchozí hodnoty používá roli virtuálního počítače Azure a název virtuálního počítače. V kontextu Azure Batch příklad ukazuje, jak místo toho použít název fondu a název výpočetního uzlu. K přepsání výchozích hodnot použijte inicializátor telemetrie .

using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
using System;
using System.Threading;

namespace Microsoft.Azure.Batch.Samples.TelemetryInitializer
{
    public class AzureBatchNodeTelemetryInitializer : ITelemetryInitializer
    {
        // Azure Batch environment variables
        private const string PoolIdEnvironmentVariable = "AZ_BATCH_POOL_ID";
        private const string NodeIdEnvironmentVariable = "AZ_BATCH_NODE_ID";

        private string roleInstanceName;
        private string roleName;

        public void Initialize(ITelemetry telemetry)
        {
            if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
            {
                // override the role name with the Azure Batch Pool name
                string name = LazyInitializer.EnsureInitialized(ref this.roleName, this.GetPoolName);
                telemetry.Context.Cloud.RoleName = name;
            }

            if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleInstance))
            {
                // override the role instance with the Azure Batch Compute Node name
                string name = LazyInitializer.EnsureInitialized(ref this.roleInstanceName, this.GetNodeName);
                telemetry.Context.Cloud.RoleInstance = name;
            }
        }

        private string GetPoolName()
        {
            return Environment.GetEnvironmentVariable(PoolIdEnvironmentVariable) ?? string.Empty;
        }

        private string GetNodeName()
        {
            return Environment.GetEnvironmentVariable(NodeIdEnvironmentVariable) ?? string.Empty;
        }
    }
}

Pokud chcete povolit inicializátor telemetrie, ApplicationInsights.config soubor v projektu TopNWordsSample obsahuje následující:

<TelemetryInitializers>
    <Add Type="Microsoft.Azure.Batch.Samples.TelemetryInitializer.AzureBatchNodeTelemetryInitializer, Microsoft.Azure.Batch.Samples.TelemetryInitializer"/>
</TelemetryInitializers>

Aktualizujte úlohu a úkoly tak, aby zahrnovaly binární soubory Application Insights.

Aby služba Application Insights běžela na výpočetních uzlech správně, ujistěte se, že jsou binární soubory správně umístěné. Přidejte požadované binární soubory do kolekce souborů prostředků úkolu, aby se stáhly při spuštění úlohy. Následující fragmenty kódu se podobají kódu v Job.cs.

Nejprve vytvořte statický seznam souborů Application Insights k nahrání.

private static readonly List<string> AIFilesToUpload = new List<string>()
{
    // Application Insights config and assemblies
    "ApplicationInsights.config",
    "Microsoft.ApplicationInsights.dll",
    "Microsoft.AI.Agent.Intercept.dll",
    "Microsoft.AI.DependencyCollector.dll",
    "Microsoft.AI.PerfCounterCollector.dll",
    "Microsoft.AI.ServerTelemetryChannel.dll",
    "Microsoft.AI.WindowsServer.dll",
    
    // custom telemetry initializer assemblies
    "Microsoft.Azure.Batch.Samples.TelemetryInitializer.dll",
 };
...

Dále vytvořte pracovní soubory, které jsou používány úlohou.

...
// create file staging objects that represent the executable and its dependent assembly to run as the task.
// These files are copied to every node before the corresponding task is scheduled to run on that node.
FileToStage topNWordExe = new FileToStage(TopNWordsExeName, stagingStorageAccount);
FileToStage storageDll = new FileToStage(StorageClientDllName, stagingStorageAccount);

// Upload Application Insights assemblies
List<FileToStage> aiStagedFiles = new List<FileToStage>();
foreach (string aiFile in AIFilesToUpload)
{
    aiStagedFiles.Add(new FileToStage(aiFile, stagingStorageAccount));
}
...

Metoda FileToStage je pomocná funkce ve vzorovém kódu, která umožňuje snadno nahrát soubor z místního disku do objektu blob služby Azure Storage. Každý soubor se později stáhne do výpočetního uzlu a odkazuje na ho úkol.

Nakonec přidejte úkoly do úlohy a zahrňte potřebné binární soubory Application Insights.

...
// initialize a collection to hold the tasks that will be submitted in their entirety
List<CloudTask> tasksToRun = new List<CloudTask>(topNWordsConfiguration.NumberOfTasks);
for (int i = 1; i <= topNWordsConfiguration.NumberOfTasks; i++)
{
    CloudTask task = new CloudTask("task_no_" + i, String.Format("{0} --Task {1} {2} {3} {4}",
        TopNWordsExeName,
        string.Format("https://{0}.blob.core.windows.net/{1}",
            accountSettings.StorageAccountName,
            documents[i]),
        topNWordsConfiguration.TopWordCount,
        accountSettings.StorageAccountName,
        accountSettings.StorageAccountKey));

    //This is the list of files to stage to a container -- for each job, one container is created and 
    //files all resolve to Azure Blobs by their name (so two tasks with the same named file will create just 1 blob in
    //the container).
    task.FilesToStage = new List<IFileStagingProvider>
                        {
                            // required application binaries
                            topNWordExe,
                            storageDll,
                        };
    foreach (FileToStage stagedFile in aiStagedFiles)
   {
        task.FilesToStage.Add(stagedFile);
   }    
    task.RunElevated = false;
    tasksToRun.Add(task);
}

Zobrazení dat v Azure Portal

Teď, když jste úlohu a úkoly nakonfigurovali tak, aby používaly Application Insights, spusťte ukázkovou úlohu ve svém fondu. Přejděte na Azure Portal a otevřete prostředek Application Insights, který jste zřídili. Po zřízení fondu byste měli začít sledovat tok dat a protokolování. Zbytek tohoto článku se týká jenom několika funkcí Application Insights, ale nebojte se prozkoumat celou sadu funkcí.

Zobrazení dat živého streamu

Pokud chcete zobrazit protokoly trasování v prostředku Application Insights, klikněte na Live Stream. Následující snímek obrazovky ukazuje, jak zobrazit živá data přicházející z výpočetních uzlů ve fondu, například využití procesoru na výpočetní uzel.

Snímek obrazovky s daty výpočetního uzlu živého streamu

Zobrazení protokolů trasování

Pokud chcete zobrazit protokoly trasování v prostředku Application Insights, klikněte na Hledat. Toto zobrazení zobrazuje seznam diagnostických dat zachycených službou Application Insights, včetně trasování, událostí a výjimek.

Následující snímek obrazovky ukazuje, jak se zaprotokoluje a následně dotazuje jedno trasování úkolu pro účely ladění.

Snímek obrazovky s protokoly pro jedno trasování

Zobrazení neošetřených výjimek

Application Insights protokoluje výjimky vyvolané z vaší aplikace. V takovém případě můžete během několika sekund od vyvolání výjimky přejít k podrobnostem konkrétní výjimky a diagnostikovat problém.

Snímek obrazovky s neošetřenými výjimkami

Měření času stažení objektu blob

Vlastní metriky jsou také cenným nástrojem na portálu. Můžete například zobrazit průměrnou dobu, po kterou každý výpočetní uzel stáhl požadovaný textový soubor, který zpracovával.

Vytvoření ukázkového grafu:

  1. V prostředku Application Insights klikněte na Průzkumník> metrik Přidatgraf.
  2. U přidaného grafu klikněte na Upravit .
  3. Aktualizujte podrobnosti grafu následujícím způsobem:
    • Typ grafu nastavte na Mřížka.
    • Nastavte Možnost Agregace na Průměr.
    • Nastavte Seskupit podle na NodeId.
    • V části Metriky vyberte Stažení vlastního>objektu blob v sekundách.
    • Upravte paletu barev zobrazení podle svého výběru.

Snímek obrazovky s grafem znázorňujícím čas stažení objektu blob pro jednotlivé uzly

Nepřetržité monitorování výpočetních uzlů

Možná jste si všimli, že všechny metriky, včetně čítačů výkonu, se protokolují jenom v případě, že jsou úlohy spuštěné. Toto chování je užitečné, protože omezuje množství dat, která Application Insights protokoluje. Existují však případy, kdy byste chtěli výpočetní uzly vždy monitorovat. Může například běžet práce na pozadí, která není naplánovaná prostřednictvím služby Batch. V takovém případě nastavte proces monitorování tak, aby běžel po dobu životnosti výpočetního uzlu.

Jedním ze způsobů, jak tohoto chování dosáhnout, je vytvořit proces, který načte knihovnu Application Insights a spustí se na pozadí. V tomto příkladu spouštěcí úloha načte binární soubory na počítači a udržuje proces po neomezenou dobu. Nakonfigurujte konfigurační soubor Application Insights pro tento proces tak, aby vysílil další data, která vás zajímají, například čítače výkonu.

...
 // Batch start task telemetry runner
private const string BatchStartTaskFolderName = "StartTask";
private const string BatchStartTaskTelemetryRunnerName = "Microsoft.Azure.Batch.Samples.TelemetryStartTask.exe";
private const string BatchStartTaskTelemetryRunnerAIConfig = "ApplicationInsights.config";
...
CloudPool pool = client.PoolOperations.CreatePool(
    topNWordsConfiguration.PoolId,
    targetDedicated: topNWordsConfiguration.PoolNodeCount,
    virtualMachineSize: "standard_d1_v2",
    VirtualMachineConfiguration: new VirtualMachineConfiguration(
    imageReference: new ImageReference(
                        publisher: "MicrosoftWindowsServer",
                        offer: "WindowsServer",
                        sku: "2019-datacenter-core",
                        version: "latest"),
    nodeAgentSkuId: "batch.node.windows amd64");
...

// Create a start task which will run a dummy exe in background that simply emits performance
// counter data as defined in the relevant ApplicationInsights.config.
// Note that the waitForSuccess on the start task was not set so the Compute Node will be
// available immediately after this command is run.
pool.StartTask = new StartTask()
{
    CommandLine = string.Format("cmd /c {0}", BatchStartTaskTelemetryRunnerName),
    ResourceFiles = resourceFiles
};
...

Tip

Pokud chcete zvýšit možnosti správy vašeho řešení, můžete sestavení sbalit do balíčku aplikace. Pokud pak chcete balíček aplikace nasadit automaticky do fondů, přidejte do konfigurace fondu odkaz na balíček aplikace.

Omezení a ukázková data

Vzhledem k rozsáhlé povaze Azure Batch aplikací běžících v produkčním prostředí můžete chtít omezit množství dat shromažďovaných službou Application Insights kvůli správě nákladů. Některé mechanismy, jak toho dosáhnout , najdete v tématu Vzorkování v Application Insights .

Další kroky