Monitorowanie i debugowanie aplikacji platformy .NET usługi Azure Batch za pomocą usługi Application Insights

Usługa Application Insights zapewnia elegancki i zaawansowany sposób, w jaki deweloperzy mogą monitorować i debugować aplikacje wdrożone w usługach platformy Azure. Usługa Application Insights służy do monitorowania liczników wydajności i wyjątków, a także instrumentacji kodu za pomocą metryk niestandardowych i śledzenia. Zintegrowanie usługi Application Insights z aplikacją usługi Azure Batch pozwala uzyskać szczegółowy wgląd w zachowania i zbadać problemy niemal w czasie rzeczywistym.

W tym artykule pokazano, jak dodać i skonfigurować bibliotekę usługi Application Insights do rozwiązania .NET usługi Azure Batch i instrumentować kod aplikacji. Przedstawiono również sposoby monitorowania aplikacji za pośrednictwem witryny Azure Portal i tworzenia niestandardowych pulpitów nawigacyjnych. Aby uzyskać informacje o obsłudze usługi Application Insights w innych językach, zobacz dokumentację języków, platform i integracji.

Przykładowe rozwiązanie w języku C# z kodem towarzyszącym temu artykułowi jest dostępne w witrynie GitHub. W tym przykładzie dodano kod instrumentacji usługi Application Insights do przykładu TopNWords . Jeśli nie znasz tego przykładu, spróbuj najpierw utworzyć i uruchomić narzędzie TopNWords. Wykonanie tego pomaga zrozumieć podstawowy przepływ pracy w usłudze Batch polegający na równoległym przetwarzaniu zestawu wejściowych obiektów blob w wielu węzłach obliczeniowych.

Wymagania wstępne

Dodaj usługę Application Insights do swojego projektu

Pakiet NuGet Microsoft.ApplicationInsights.WindowsServer i jego zależności są wymagane dla projektu. Dodaj lub przywróć je do projektu aplikacji. Aby zainstalować pakiet, użyj polecenia Install-Package lub Menedżera pakietów NuGet.

Install-Package Microsoft.ApplicationInsights.WindowsServer

Odwołuj się do usługi Application Insights z aplikacji .NET przy użyciu przestrzeni nazw Microsoft.ApplicationInsights.

Instrumentuj swój kod

Aby instrumentować kod, rozwiązanie musi utworzyć obiekt TelemetryClient usługi Application Insights. W tym przykładzie klient TelemetryClient ładuje konfigurację z pliku ApplicationInsights.config . Pamiętaj, aby zaktualizować plik ApplicationInsights.config w następujących projektach przy użyciu klucza instrumentacji usługi Application Insights: Microsoft.Azure.Batch.Samples.TelemetryStartTask i TopNWordsSample.

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

Dodaj również klucz instrumentacji w pliku TopNWords.cs.

W przykładzie w pliku TopNWords.cs użyto następujących wywołań instrumentujących interfejsu API usługi Application Insights:

  • TrackMetric() — śledzi średni czas pobierania wymaganego pliku tekstowego przez węzeł obliczeniowy.
  • TrackTrace() — Dodaje wywołania debugowania do kodu.
  • TrackEvent() - Monitoruje istotne zdarzenia do zarejestrowania.

W tym przykładzie celowo pomija się obsługę wyjątków. Zamiast tego usługa Application Insights automatycznie zgłasza nieobsługiwane wyjątki, co znacznie poprawia środowisko debugowania.

Poniższy fragment kodu ilustruje sposób używania tych metod.

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

Pomocnik inicjatora telemetrii usługi Azure Batch

Podczas raportowania danych telemetrycznych dla danego serwera i wystąpienia usługa Application Insights używa roli i nazwy maszyny wirtualnej platformy Azure dla wartości domyślnych. W kontekście usługi Azure Batch przykład pokazuje, jak zamiast tego używać nazwy puli i nazwy węzła obliczeniowego. Użyj inicjatora telemetrii, aby zastąpić wartości domyślne.

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

Aby włączyć inicjator telemetrii, plik ApplicationInsights.config w projekcie TopNWordsSample zawiera następujące elementy:

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

Aktualizowanie zadania i zadań w celu uwzględnienia plików binarnych usługi Application Insights

Aby usługa Application Insights mogła działać poprawnie w węzłach obliczeniowych, upewnij się, że pliki binarne są poprawnie umieszczone. Dodaj wymagane pliki binarne do kolekcji plików zasobów zadania, aby były pobierane podczas wykonywania zadania. Poniższe fragmenty kodu są podobne do kodu w Job.cs.

Najpierw utwórz statyczną listę plików usługi Application Insights do przesłania.

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

Następnie utwórz pliki przejściowe, które są używane przez zadanie.

...
// 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 jest funkcją pomocnika w przykładzie kodu, która umożliwia łatwe przekazywanie pliku z dysku lokalnego do obiektu blob usługi Azure Storage. Każdy plik jest następnie pobierany na węzeł obliczeniowy, a zadanie odwołuje się do niego.

Na koniec dodaj zadania do zadania i uwzględnij niezbędne pliki binarne usługi 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);
}

Wyświetlanie danych w portalu Azure

Po skonfigurowaniu zadania i zadań do korzystania z usługi Application Insights uruchom przykładowe zadanie w puli. Przejdź do witryny Azure Portal i otwórz zasób usługi Application Insights, który został aprowizowany. Po aprowizacji puli należy zacząć widzieć przepływ danych i zalogować się. W pozostałej części tego artykułu omówiono tylko kilka funkcji usługi Application Insights, ale możesz zapoznać się z pełnym zestawem funkcji.

Wyświetlanie danych transmisji strumieniowej na żywo

Aby wyświetlić dzienniki śledzenia w zasobie usługi Application Insights, wybierz pozycję Transmisja strumieniowa na żywo. Poniższy zrzut ekranu przedstawia sposób wyświetlania danych na żywo pochodzących z węzłów obliczeniowych w puli, na przykład użycia procesora CPU na węzeł obliczeniowy.

Zrzut ekranu z danymi węzła obliczeniowego transmisji na żywo.

Wyświetl dzienniki śledzenia

Aby wyświetlić dzienniki śledzenia w zasobie usługi Application Insights, wybierz pozycję Wyszukaj. Ten widok przedstawia listę danych diagnostycznych przechwyconych przez usługę Application Insights, w tym ślady, zdarzenia i wyjątki.

Poniższy zrzut ekranu przedstawia sposób rejestrowania pojedynczego śladu zadania i późniejszego wykonywania zapytań na potrzeby debugowania.

Zrzut ekranu przedstawiający logi dla pojedynczego śladu.

Wyświetl nieobsłużone wyjątki

Usługa Application Insights rejestruje wyjątki zgłaszane przez Twoją aplikację. W takim przypadku w ciągu kilku sekund od zgłoszenia wyjątku przez aplikację możesz przeanalizować konkretny wyjątek i zdiagnozować problem.

Zrzut ekranu przedstawiający nieobsługiwane wyjątki.

Zmierz czas pobierania obiektu blob

Metryki niestandardowe są również cennym narzędziem w portalu. Można na przykład wyświetlić średni czas potrzebny na pobranie wymaganego pliku tekstowego, który przetwarzał każdy węzeł obliczeniowy.

Aby utworzyć przykładowy wykres:

  1. W zasobie usługi Application Insights wybierz pozycję Eksplorator metryk>Dodaj wykres.
  2. Wybierz pozycję Edytuj na dodanym wykresie.
  3. Zaktualizuj szczegóły wykresu w następujący sposób:
    • Ustaw typ wykresu na Siatka.
    • Ustaw pozycję Agregacja na Wartość Średnia.
    • Ustaw Grupuj według na NodeId.
    • W sekcji Metryki wybierz pozycję Niestandardowe>Pobieranie obiektu blob w sekundach.
    • Dostosuj paletę kolorów wyświetlania do wybranej opcji.

Zrzut ekranu wykresu przedstawiającego czas pobierania obiektów blob dla każdego węzła.

Ciągłe monitorowanie węzłów obliczeniowych

Być może zauważysz, że wszystkie metryki, w tym liczniki wydajności, są rejestrowane tylko wtedy, gdy zadania są uruchomione. To zachowanie jest przydatne, ponieważ ogranicza ilość danych dzienników usługi Application Insights. Istnieją jednak przypadki, w których zawsze chcesz monitorować węzły obliczeniowe. Na przykład mogą wykonywać pracę w tle, która nie jest zaplanowana za pomocą usługi Batch. W takim przypadku skonfiguruj proces monitorowania, aby był uruchamiany przez okres eksploatacji węzła obliczeniowego.

Jednym ze sposobów osiągnięcia tego zachowania jest zduplikowanie procesu, który ładuje bibliotekę usługi Application Insights i działa w tle. W tym przykładzie zadanie uruchamiania ładuje pliki binarne na maszynie i utrzymuje proces uruchomiony w nieskończoność. Skonfiguruj plik konfiguracji usługi Application Insights dla tego procesu, aby emitować interesujące Cię dodatkowe dane, takie jak liczniki wydajności.

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

Wskazówka

Aby ułatwić zarządzanie rozwiązaniem, możesz dołączyć zestaw do pakietu aplikacji. Następnie aby automatycznie wdrożyć pakiet aplikacji do pul, dodaj odwołanie do pakietu aplikacji do konfiguracji puli.

Ograniczanie i próbkowanie danych

Ze względu na duży charakter aplikacji usługi Azure Batch działających w środowisku produkcyjnym możesz ograniczyć ilość danych zbieranych przez usługę Application Insights w celu zarządzania kosztami. Zobacz Próbkowanie w usłudze Application Insights , aby zapoznać się z pewnymi mechanizmami, aby to osiągnąć.

Następne kroki

  • Dowiedz się więcej o usłudze Application Insights.
  • Aby uzyskać informacje o obsłudze usługi Application Insights w innych językach, zobacz dokumentację języków, platform i integracji.