分享方式:


使用 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 工作流程。

提示

或者,將您的 Batch 解決方案設定為顯示 Application Insights 資料,例如 Batch Explorer 中的 VM 效能計數器。 Batch Explorer是免費、功能豐富、獨立用戶端的工具,可以協助建立、偵錯及監視 Azure Batch 應用程式。 下載適用於 Mac、Linux 或 Windows 的安裝套件。 如需在 Batch Explorer 中啟用 Application Insights 資料的快速步驟,請參閱 batch-insights 存放庫

必要條件

將 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 中的取樣,以了解完成此操作的一些機制。

下一步