Dela via


Övervaka och felsöka ett Azure Batch .NET-program med Application Insights

Application Insights är ett elegant och kraftfullt sätt för utvecklare att övervaka och felsöka program som distribueras till Azure-tjänster. Använd Application Insights för att övervaka prestandaräknare och undantag samt instrumentera koden med anpassade mått och spårning. Genom att integrera Application Insights med ditt Azure Batch-program kan du få djupgående insikter om beteenden och undersöka problem i nästan realtid.

Den här artikeln visar hur du lägger till och konfigurerar Application Insights-biblioteket i din Azure Batch .NET-lösning och instrumentera programkoden. Den visar också sätt att övervaka ditt program via Azure Portal och skapa anpassade instrumentpaneler. Information om Stöd för Application Insights på andra språk finns i dokumentationen om språk, plattformar och integreringar.

En C#-exempellösning med kod som medföljer den här artikeln finns på GitHub. Det här exemplet lägger till Application Insights-instrumentationskod i TopNWords-exemplet . Om du inte är bekant med det exemplet kan du prova att skapa och köra TopNWords först. Detta hjälper dig att förstå ett grundläggande Batch-arbetsflöde för bearbetning av en uppsättning indatablobar parallellt på flera beräkningsnoder.

Förutsättningar

Lägg till Application Insights i projektet

NuGet-paketet Microsoft.ApplicationInsights.WindowsServer och dess beroenden krävs för projektet. Lägg till eller återställ dem i programmets projekt. Om du vill installera paketet använder du Install-Package kommandot eller NuGet Package Manager.

Install-Package Microsoft.ApplicationInsights.WindowsServer

Referera till Application Insights från ditt .NET-program med hjälp av namnområdet Microsoft.ApplicationInsights .

Instrumentera koden

För att instrumentera koden måste lösningen skapa en Application Insights TelemetryClient. I exemplet läser TelemetryClient in sin konfiguration från filen ApplicationInsights.config . Se till att uppdatera ApplicationInsights.config i följande projekt med din Application Insights-instrumentationsnyckel: Microsoft.Azure.Batch.Samples.TelemetryStartTask och TopNWordsSample.

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

Lägg också till instrumentationsnyckeln i filen TopNWords.cs.

Exemplet i TopNWords.cs använder följande instrumentationsanrop från Application Insights API:

  • TrackMetric() – Spårar hur lång tid det tar för en beräkningsnod att ladda ned den textfil som krävs.
  • TrackTrace() – Lägger till felsökningsanrop i koden.
  • TrackEvent() - Spårar intressanta händelser att fånga.

Det här exemplet utelämnar avsiktligt undantagshantering. I stället rapporterar Application Insights automatiskt ohanterade undantag, vilket avsevärt förbättrar felsökningsupplevelsen.

Följande kodfragment visar hur du använder dessa metoder.

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

Hjälp för Azure Batch-telemetriinitierare

När du rapporterar telemetri för en viss server och instans använder Application Insights azure vm-rollen och vm-namnet för standardvärdena. I azure batch-kontexten visar exemplet hur du använder poolnamnet och beräkningsnodnamnet i stället. Använd en telemetriinitierare för att åsidosätta standardvärdena.

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;
        }
    }
}

Om du vill aktivera telemetriinitieraren innehåller applicationinsights.config-filen i TopNWordsSample-projektet följande:

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

Uppdatera jobbet och uppgifterna så att de inkluderar Application Insights-binärfiler

För att Application Insights ska kunna köras korrekt på dina beräkningsnoder kontrollerar du att binärfilerna är korrekt placerade. Lägg till de nödvändiga binärfilerna i din uppgifts resursfilsamling så att de laddas ned när aktiviteten körs. Följande kodfragment liknar kod i Job.cs.

Skapa först en statisk lista över Application Insights-filer som ska laddas upp.

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",
 };
...

Skapa sedan mellanlagringsfilerna som används av uppgiften.

...
// 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));
}
...

Metoden FileToStage är en hjälpfunktion i kodexemplet som gör att du enkelt kan ladda upp en fil från en lokal disk till en Azure Storage-blob. Varje fil laddas senare ned till en beräkningsnod och refereras av en uppgift.

Lägg slutligen till aktiviteterna i jobbet och inkludera nödvändiga Application Insights-binärfiler.

...
// 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);
}

Visa data i Azure-portalen

Nu när du har konfigurerat jobbet och uppgifterna för att använda Application Insights kör du exempeljobbet i poolen. Gå till Azure Portal och öppna den Application Insights-resurs som du etablerade. När poolen har etablerats bör du börja se data som flödar och loggas. Resten av den här artikeln berör bara några få Application Insights-funktioner, men du kan utforska hela funktionsuppsättningen.

Visa liveströmsdata

Om du vill visa spårningsloggar i din Application Insights-resurs klickar du på Live Stream. Följande skärmbild visar hur du visar livedata som kommer från beräkningsnoderna i poolen, till exempel CPU-användningen per beräkningsnod.

Skärmbild av data för beräkningsnoder för liveström.

Visa spårningsloggar

Om du vill visa spårningsloggar i din Application Insights-resurs klickar du på Sök. Den här vyn visar en lista över diagnostikdata som samlas in av Application Insights, inklusive spårningar, händelser och undantag.

Följande skärmbild visar hur en enda spårning för en uppgift loggas och senare efterfrågas i felsökningssyfte.

Skärmbild som visar loggar för en enda spårning.

Visa ohanterade undantag

Application Insights loggar undantag som genereras från ditt program. I det här fallet, inom några sekunder efter att programmet utlöste undantaget, kan du gå in på ett specifikt undantag och diagnostisera problemet.

Skärmbild som visar ohanterade undantag.

Mäta tiden för blobnedladdning

Anpassade mått är också ett värdefullt verktyg i portalen. Du kan till exempel visa den genomsnittliga tid det tog för varje beräkningsnod att ladda ned den obligatoriska textfil som bearbetades.

Så här skapar du ett exempeldiagram:

  1. I Application Insights-resursen klickar du på Måttutforskaren>Lägg till diagram.
  2. Klicka på Redigera i diagrammet som lades till.
  3. Uppdatera diagraminformationen enligt följande:
    • Ange Diagramtyp till Rutnät.
    • Ange aggregering till Genomsnitt.
    • Ange Gruppera efter till NodeId.
    • I Mått väljer du Ladda ned anpassad>blob i sekunder.
    • Justera visningsfärgpaletten efter val.

Skärmbild av ett diagram som visar tiden för blobnedladdning per nod.

Övervaka beräkningsnoder kontinuerligt

Du kanske har märkt att alla mått, inklusive prestandaräknare, bara loggas när aktiviteterna körs. Det här beteendet är användbart eftersom det begränsar mängden data som Application Insights loggar. Det finns dock fall då du alltid vill övervaka beräkningsnoderna. De kan till exempel köra bakgrundsarbete som inte är schemalagt via Batch-tjänsten. I det här fallet konfigurerar du en övervakningsprocess som ska köras under beräkningsnodens livslängd.

Ett sätt att uppnå det här beteendet är att skapa en process som läser in Application Insights-biblioteket och körs i bakgrunden. I exemplet läser startaktiviteten in binärfilerna på datorn och håller en process igång på obestämd tid. Konfigurera Application Insights-konfigurationsfilen för den här processen för att generera ytterligare data som du är intresserad av, till exempel prestandaräknare.

...
 // 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
};
...

Dricks

Om du vill öka hanterbarheten för din lösning kan du paketera sammansättningen i ett programpaket. Om du sedan vill distribuera programpaketet automatiskt till dina pooler lägger du till en programpaketreferens till poolkonfigurationen.

Begränsning och exempeldata

På grund av den storskaliga karaktären hos Azure Batch-program som körs i produktion kanske du vill begränsa mängden data som samlas in av Application Insights för att hantera kostnader. Se Sampling i Application Insights för några mekanismer för att uppnå detta.

Nästa steg

  • Läs mer om Application Insights.
  • Information om Stöd för Application Insights på andra språk finns i dokumentationen om språk, plattformar och integreringar.