共用方式為


使用 Application Insights 監視 Azure Batch .NET 應用程式並進行偵錯

Application Insights 提供開發人員精緻且強大的方法,用來監視部署到 Azure 服務的應用程式並進行偵錯。 使用 Application Insights 監視效能計數器和例外狀況,以及透過自訂計量與追蹤來檢測您的程式碼。 整合 Application Insights 與 Azure Batch 應用程式可讓您取得行為的深入見解,並幾近即時地調查問題。

本文會示範如何將 Application Insights 程式庫新增至您的 Azure Batch .NET 解決方案並加以設定,以及檢測應用程式的程式碼。 同時示範透過 Azure 入口網站監視應用程式和建置自訂儀表板的方法。 如需了解其他語言中的 Application Insights 支援,請參閱語言、平台及整合文件

隨附於本文的 C# 解決方案範例與程式碼可於 GitHub 中取得。 此範例會將 Application Insights 檢測程式碼新增至 TopNWords 範例。 如果您不熟悉該範例,請先嘗試建置及執行 TopNWords。 這麼做可協助您了解在多個計算節點上平行處理一組輸入 Blob 的基本 Batch 工作流程。

必要條件

將 Application Insights 新增到專案

您的專案需要 Microsoft.ApplicationInsights.WindowsServer NuGet 套件和其相依項目。 可將其新增或還原到您應用程式的專案。 若要安裝套件,請使用 Install-Package 命令或 NuGet 套件管理員。

Install-Package Microsoft.ApplicationInsights.WindowsServer

您可以使用 Microsoft.ApplicationInsights 命名空間從您的 .NET 應用程式參考 Application Insights。

實作您的程式碼

若要檢測您的程式碼,您的解決方案必須建立 Application Insights TelemetryClient。 在範例中,TelemetryClient 會從 ApplicationInsights.config 檔案載入其組態。 請務必使用您的 Application Insights 檢測金鑰來更新下列專案中的 ApplicationInsights.config:Microsoft.Azure.Batch.Samples.TelemetryStartTask and TopNWordsSample。

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

也請將檢測金鑰新增至 TopNWords.cs 檔案。

TopNWords.cs 中的範例會使用 Application Insights API 中的下列檢測呼叫

  • TrackMetric() - 追蹤計算節點下載必要文字檔案要多久時間 (平均值)。
  • TrackTrace() - 將偵錯呼叫新增至您的程式碼。
  • TrackEvent() - 追蹤要擷取的關注事件。

此範例刻意省去例外狀況處理。 改為 Application Insights 會自動報告未處理的例外狀況,進而大幅改善偵錯體驗。

下列程式碼片段說明如何使用這些方法。

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

Azure Batch 遙測初始設定式的協助程式

報告指定伺服器和執行個體的遙測時,Application Insights 會使用 Azure VM 角色和 VM 名稱作為預設值。 在 Azure Batch 的執行內容中,此範例會改為示範如何使用集區名稱和計算節點名稱。 使用遙測初始設定式覆寫預設值。

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

若要啟用遙測初始設定式,TopNWordsSample 專案中的 ApplicationInsights.config 檔案包含下列內容:

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

更新作業和工作,以包含 Application Insights 二進位檔

為了讓 Application Insights 在節點上正確地執行,請確定二進位檔位於正確位置。 請將所需的二進位檔新增至您工作資源檔案的集合,使其能在工作執行時加以下載。 下列程式碼片段類似於 Job.cs 中的程式碼。

首先,建立要上傳的 Application Insights 檔案靜態清單。

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

接下來,建立工作要使用的暫存檔案。

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

FileToStage 方法是程式碼範例中的協助程式函式,可讓您輕鬆地將檔案從本機磁碟中上傳至 Azure 儲存體 Blob。 稍後每個檔都會下載到計算節點,並且讓工作參考。

最後,將工作新增至作業,並包含必要的 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);
}

檢視 Azure 入口網站中的資料

現在您已設定了使用 Application Insights 的作業和工作,接下來請在工作集區中執行範例。 瀏覽至 Azure 入口網站,並開啟您佈建的 Application Insights 資源。 集區佈建好之後,您應會開始看到資料的流動與記錄。 本文其餘部分只會說明幾個 Application Insights 功能,但您可以隨意地探索完整的功能集。

檢視即時資料流

若要檢視 Application Insights 資源中的追蹤記錄,請按一下 [即時資料流]。 下列螢幕擷取畫面說明如何檢視來自集區中計算節點的即時資料,例如每個計算節點的 CPU 使用量。

即時串流計算節點資料的螢幕擷取畫面。

檢視追蹤記錄

若要檢視 Application Insights 資源中的追蹤記錄,請按一下 [搜尋]。 此檢視會顯示 Application Insights 所擷取的診斷資料清單,其中包括追蹤、事件和例外狀況。

下列螢幕擷取畫面說明單一工作追蹤的記錄方式,以及之後進行偵錯所需的查詢方式。

顯示單一追蹤記錄的螢幕擷取畫面。

檢視未處理的例外狀況

Application Insights 會記錄從您的應用程式擲回的例外狀況。 在此案例中,在應用程式擲回例外狀況的幾秒內,您就可以深入了解特定例外狀況並診斷問題。

顯示未處理的例外狀況的螢幕擷取畫面。

測量 Blob 下載時間

自訂計量也是入口網站中的實用工具。 例如,您可以顯示每個計算節點下載所處理的必要文字檔案時,所花費的平均時間。

建立範例圖表:

  1. 在 Application Insights 資源中,按一下 [計量瀏覽器]>[新增圖表]
  2. 在新增的圖表上按一下 [編輯]
  3. 更新圖表的詳細資料,如下所示:
    • 將 [圖表類型] 設定為 [方格]
    • 將 [彙總] 設定為 [平均]
    • 將 [分組依據] 設定為 [NodeId]
    • 在 [計量] 中,選取 [自訂]>[Blob 下載 (以秒為單位)]
    • 您可以依喜好調整顯示的 [色彩調色盤]

顯示每個節點 Blob 下載時間圖表的螢幕擷取畫面。

持續監視計算節點

您可能已注意到,只有在工作執行時才會記錄所有計量 (包括效能計數器)。 此行為是非常實用,因為這會限制 Application Insights 記錄的資料量。 不過,在某些情況下,您可能需要一直監視計算節點。 例如,這些計算節點執行的背景工作可能未透過 Batch 服務進行排程。 在此情況下,請針對計算節點的存留期,設定要執行的監視程序。

要完成此行為的方法之一是繁衍程序來載入 Application Insights 程式庫,並在背景中執行。 在範例中,啟動工作會在機器上載入二進位檔,並會無限期地持續執行處理程序。 設定此處理程序的 Application Insights 組態檔,以發出您關注的其他資料,例如效能計數器。

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

提示

若要增加解決方案的可管理性,您可以搭配應用程式套件中的組件。 然後,若要讓應用程式套件自動部署至您的集區,請將應用程式套件參考新增至集區組態。

節流和範例資料

由於在生產環境中執行的 Azure Batch 應用程式本質上都是大規模運作,因此建議您藉由限制 Application Insights 所收集的資料量來管理成本。 請參閱 Application Insights 中的取樣,以了解完成此操作的一些機制。

下一步