Monitorar e depurar um aplicativo .NET do Azure Batch com o Application Insights
O Application Insights fornece uma maneira elegante e poderosa para os desenvolvedores monitorarem e depurarem aplicativos implantados nos serviços do Azure. Use o Application Insights para monitorar contadores de desempenho e exceções, bem como instrumentar seu código com métricas e rastreamento personalizados. A integração do Application Insights com seu aplicativo Azure Batch permite que você obtenha insights profundos sobre comportamentos e investigue problemas quase em tempo real.
Este artigo mostra como adicionar e configurar a biblioteca do Application Insights em sua solução .NET do Azure Batch e instrumentar o código do aplicativo. Ele também mostra maneiras de monitorar seu aplicativo por meio do portal do Azure e criar painéis personalizados. Para obter suporte ao Application Insights em outros idiomas, consulte a documentação de idiomas, plataformas e integrações.
Um exemplo de solução C# com código para acompanhar este artigo está disponível no GitHub. Este exemplo adiciona o código de instrumentação do Application Insights ao exemplo TopNWords . Se você não estiver familiarizado com esse exemplo, tente criar e executar o TopNWords primeiro. Isso ajudará você a entender um fluxo de trabalho básico de lote de processamento de um conjunto de blobs de entrada em paralelo em vários nós de computação.
Gorjeta
Como alternativa, configure sua solução em lote para exibir dados do Application Insights, como contadores de desempenho de VM no Batch Explorer. O Batch Explorer é uma ferramenta de cliente autônoma, autônoma e com recursos avançados para ajudar a criar, depurar e monitorar aplicativos do Azure Batch. Transfira um pacote de instalação para Mac, Linux ou Windows. Consulte o repositório batch-insights para obter etapas rápidas para habilitar os dados do Application Insights no Batch Explorer.
Pré-requisitos
Recurso do Application Insights. Use o portal do Azure para criar um recurso do Application Insights. Selecione o tipo de Aplicação Geral.
Copie a chave de instrumentação do portal do Azure. Você precisará desse valor mais tarde.
Nota
Você pode ser cobrado pelos dados armazenados no Application Insights. Isso inclui os dados de diagnóstico e monitoramento discutidos neste artigo.
Adicionar as Informações da Aplicação ao seu projeto
O pacote NuGet Microsoft.ApplicationInsights.WindowsServer e suas dependências são necessários para seu projeto. Adicione-os ou restaure-os ao projeto do seu aplicativo. Para instalar o pacote, use o comando ou o Install-Package
Gerenciador de Pacotes NuGet.
Install-Package Microsoft.ApplicationInsights.WindowsServer
Faça referência ao Application Insights de seu aplicativo .NET usando o namespace Microsoft.ApplicationInsights .
Instrumente o seu código
Para instrumentar seu código, sua solução precisa criar um Application Insights TelemetryClient. No exemplo, o TelemetryClient carrega sua configuração do arquivo ApplicationInsights.config . Certifique-se de atualizar o ApplicationInsights.config nos seguintes projetos com sua chave de instrumentação do Application Insights: Microsoft.Azure.Batch.Samples.TelemetryStartTask e TopNWordsSample.
<InstrumentationKey>YOUR-IKEY-GOES-HERE</InstrumentationKey>
Adicione também a chave de instrumentação no arquivo TopNWords.cs.
O exemplo no TopNWords.cs usa as seguintes chamadas de instrumentação da API do Application Insights:
TrackMetric()
- Rastreia quanto tempo, em média, um nó de computação leva para baixar o arquivo de texto necessário.TrackTrace()
- Adiciona chamadas de depuração ao seu código.TrackEvent()
- Rastreia eventos interessantes para capturar.
Este exemplo propositadamente deixa de fora o tratamento de exceções. Em vez disso, o Application Insights relata automaticamente exceções não tratadas, o que melhora significativamente a experiência de depuração.
O trecho a seguir ilustra como usar esses métodos.
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");
}
}
Auxiliar do inicializador de telemetria do Azure Batch
Ao relatar telemetria para um determinado servidor e instância, o Application Insights usa a Função VM do Azure e o nome da VM para os valores padrão. No contexto do Lote do Azure, o exemplo mostra como usar o nome do pool e o nome do nó de computação. Use um inicializador de telemetria para substituir os valores padrão.
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;
}
}
}
Para habilitar o inicializador de telemetria, o arquivo ApplicationInsights.config no projeto TopNWordsSample inclui o seguinte:
<TelemetryInitializers>
<Add Type="Microsoft.Azure.Batch.Samples.TelemetryInitializer.AzureBatchNodeTelemetryInitializer, Microsoft.Azure.Batch.Samples.TelemetryInitializer"/>
</TelemetryInitializers>
Atualizar o trabalho e as tarefas para incluir binários do Application Insights
Para que o Application Insights seja executado corretamente em seus nós de computação, verifique se os binários estão colocados corretamente. Adicione os binários necessários à coleção de arquivos de recursos da tarefa para que eles sejam baixados no momento em que a tarefa for executada. Os trechos a seguir são semelhantes ao código no Job.cs.
Primeiro, crie uma lista estática de arquivos do Application Insights para carregar.
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",
};
...
Em seguida, crie os arquivos de preparo usados pela tarefa.
...
// 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));
}
...
O FileToStage
método é uma função auxiliar no exemplo de código que permite carregar facilmente um arquivo do disco local para um blob de Armazenamento do Azure. Cada arquivo é posteriormente baixado para um nó de computação e referenciado por uma tarefa.
Por fim, adicione as tarefas ao trabalho e inclua os binários necessários do 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);
}
Ver dados no portal do Azure
Agora que você configurou o trabalho e as tarefas para usar o Application Insights, execute o trabalho de exemplo em seu pool. Navegue até o portal do Azure e abra o recurso do Application Insights que você provisionou. Depois que o pool for provisionado, você deve começar a ver os dados fluindo e sendo registrados. O restante deste artigo aborda apenas alguns recursos do Application Insights, mas sinta-se à vontade para explorar todo o conjunto de recursos.
Ver dados de transmissão ao vivo
Para exibir logs de rastreamento no recurso do Applications Insights, clique em Transmissão ao vivo. A captura de tela a seguir mostra como exibir dados em tempo real provenientes dos nós de computação no pool, por exemplo, o uso da CPU por nó de computação.
Exibir logs de rastreamento
Para exibir logs de rastreamento no recurso do Applications Insights, clique em Pesquisar. Esta exibição mostra uma lista de dados de diagnóstico capturados pelo Application Insights, incluindo rastreamentos, eventos e exceções.
A captura de tela a seguir mostra como um único rastreamento para uma tarefa é registrado e posteriormente consultado para fins de depuração.
Exibir exceções não tratadas
O Application Insights registra exceções lançadas do seu aplicativo. Nesse caso, em segundos após o aplicativo lançar a exceção, você pode detalhar uma exceção específica e diagnosticar o problema.
Meça o tempo de download do blob
As métricas personalizadas também são uma ferramenta valiosa no portal. Por exemplo, você pode exibir o tempo médio que cada nó de computação levou para baixar o arquivo de texto necessário que estava processando.
Para criar um gráfico de exemplo:
- No recurso do Application Insights, clique em Metrics Explorer>Add chart.
- Clique em Editar no gráfico que foi adicionado.
- Atualize os detalhes do gráfico da seguinte maneira:
- Defina Tipo de gráfico como Grade.
- Defina a agregação como média.
- Defina Group by como NodeId.
- Em Métricas, selecione Download de Blob personalizado>em segundos.
- Ajuste a paleta de cores do ecrã à sua escolha.
Monitore nós de computação continuamente
Você deve ter notado que todas as métricas, incluindo contadores de desempenho, só são registradas quando as tarefas estão em execução. Esse comportamento é útil porque limita a quantidade de dados que o Application Insights registra. No entanto, há casos em que você sempre gostaria de monitorar os nós de computação. Por exemplo, eles podem estar executando trabalho em segundo plano que não está agendado por meio do serviço em lote. Nesse caso, configure um processo de monitoramento para ser executado durante a vida útil do nó de computação.
Uma maneira de obter esse comportamento é gerar um processo que carrega a biblioteca do Application Insights e é executado em segundo plano. No exemplo, a tarefa start carrega os binários na máquina e mantém um processo em execução indefinidamente. Configure o arquivo de configuração do Application Insights para esse processo para emitir dados adicionais nos quais você está interessado, como contadores de desempenho.
...
// 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
};
...
Gorjeta
Para aumentar a capacidade de gerenciamento de sua solução, você pode agrupar o assembly em um pacote de aplicativo. Em seguida, para implantar o pacote de aplicativos automaticamente em seus pools, adicione uma referência de pacote de aplicativo à configuração do pool.
Acelerador e dados de amostra
Devido à natureza em grande escala dos aplicativos do Lote do Azure em execução em produção, convém limitar a quantidade de dados coletados pelo Application Insights para gerenciar custos. Consulte Amostragem no Application Insights para obter alguns mecanismos para conseguir isso.
Próximos passos
- Saiba mais sobre o Application Insights.
- Para obter suporte ao Application Insights em outros idiomas, consulte a documentação de idiomas, plataformas e integrações.