A ideia é compartilhar algumas situações que já passei para instrumentar uma aplicação utilizando o recurso Application Insights, é verdade que está cada vez mais fácil de se fazer isso, principalmente nas últimas versões do .NET Core, no entanto existem cenários onde um pouco de ajuda pode poupar dias de tentativas e erros.
O Application Insights é uma ferramenta de APM (Application Performance Management), produto de monitoração de aplicações que fica dentro de um produto maior chamado Azure Monitor, solução mais abrangente para coleta, análise e ação com base na telemetria em seus ambientes de nuvem e on-premisses que ajuda a identificar de maneira proativa o desempenho de seus aplicativos e suas dependências.
Utilizar o Application Insights é uma tarefa relativamente simples principalmente quando estamos com as ultimas versões do .NET, mas temos cenários complicados, como no caso de utilização de proxy, e de plataformas mais antigas que pretendo cobrir aqui. Quando estamos no .NET Core basta instalar um SDK, em uma aplicação web, vamos usar esse pacote:
Install-Package Microsoft.ApplicationInsights.AspNetCore
O pacote pode variar de acordo com a plataforma que você estiver trabalhando, dê uma olhada aqui, vou mostrar a maior parte dos exemplos no .NET Core, mas no final do artigo eu mostro as diferenças para full framework e para windows services e consoles.
Depois você obtém a chave de instrumentação no Azure ou a connection string, e configura essa chave na sua aplicação.
Para .NET Core devemos fazer algo como isso na classe startup no método ConfigureServices:
services.AddApplicationInsightsTelemetry();
e no appsettings.json
"ApplicationInsights": {
"ConnectionString": "..."
},
Também podemos configurar nossa aplicação para direcionar os logs para o Application Insights
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.ApplicationInsights;
namespace AppInsigths
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
webBuilder.ConfigureLogging(
(context, builder) =>
{
builder.AddApplicationInsights(context.Configuration["ApplicationInsights:InstrumentationKey"]);
builder.AddFilter<ApplicationInsightsLoggerProvider>("Geral", LogLevel.Information);
});
});
}
}
Vou Criar uma Controller Simples para enviar algumas informações de logs e telemetria
using Microsoft.ApplicationInsights;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
namespace AppInsigths.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private readonly ILogger _logger;
private TelemetryClient _telemetry;
public WeatherForecastController(ILogger<WeatherForecastController> logger, TelemetryClient telemetry)
{
_logger = logger;
_telemetry = telemetry;
}
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
_telemetry.TrackEvent("WinGame");
_logger.LogWarning("An example of a Warning trace..");
_logger.LogError("An example of an Error level message");
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
Já podemos ver esses dados em ferramentas do Application Insights como Application Map, Live Metrics e Transaction Search.
Os dados de trackEvent ficam na tabela de log do customEvents e os dados de logs ficam na tabela de traces
no TrackTrace podemos definir o nível de severidade do trace, já o TrackEvent usamos para analisar a frequência com que um método é chamado.
Uma ferramenta que eu gosto muito do Application Insights é o Transaction Search ela permite fazer buscas apenas por palavras chaves facilitando a busca por requisições especificas.
Mas também podemos usar os filtros da ferramenta para refinar a busca
E o melhor é que podemos ver como fica consulta clicando em View in Logs, assim sabemos em quais tabelas os dados se encontram, podemos fazer modificações e aprender como funciona o KQL (Kusto Query Language)
Essa é uma forma de usar a mesma instância do Application Insights para várias aplicações diferentes e conseguir organizar os dados em espaços delimitados.
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
namespace AppInsigths
{
public class CustomTelemetryInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
{
//set custom role name here
telemetry.Context.Cloud.RoleName = "AppInsigths";
}
}
}
}
Precisa configurar na classe startup no método ConfigureServices:
services.AddSingleton<ITelemetryInitializer, CustomTelemetryInitializer>();
no arquivo _ViewImports.cshtml adicione
@inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet
no arquivo _Layout.cshtml
@Html.Raw(JavaScriptSnippet.FullScript)
No Full framework, temos diversas particularidades é muito importante consultar a documentação oficial, aqui vou mostrar os cenários que eu já passei, e nesse caso estou falando de algumas versões da família 4.X
Podemos usar aquele esquema automático no Visual studio 2019, botão direito no projeto e Clicar em Configurar Application Insights, mas eu instalei os pacotes na mão mesmo usando nuget console:
Install-Package Microsoft.ApplicationInsights.Web
Esse pacote adicionou um monte de dependências, modificou meu webconfig com os httpModules necessários, além de ter criado o arquivo ApplicationInsights.config. Caso ele não tenha sido criado acesse o modelo aqui
Depois peguei a Connection String direto do portal do Azure, no recurso do application insights escolhido, criado especificamente para a minha aplicação.
colei no arquivo ApplicationInsights.config, algo como isso, fica abaixo da sessão TelemetrySinks.
<ConnectionString>InstrumentationKey=d42120e4-dc8a-4b06-9193-5eb905de8039;IngestionEndpoint=https://centralus-2.in.applicationinsights.azure.com/;LiveEndpoint=https://centralus.livediagnostics.monitor.azure.com/</ConnectionString>
pronto já temos requisições
O deploy foi feito no AppServices do azure que está configurado com o menu Application Insights habilitado:
Segui o mesmo esquema, instalei os pacotes manualmente pelo nuget console, só que aqui instalei apenas:
Install-Package Microsoft.ApplicationInsights.WindowsServer
Tudo foi criado automaticamente o aquivo ApplicationInsights.config, mas aqui não tem webconfig, e precisamos fazer algumas implementações.
No arquivo principal do windows services, a classe que herda de ServiceBase no método OnStart usei essa implementação
protected override void OnStart(string[] args)
{
var text = $"Service Start At {DateTime.Now}";
TelemetryConfiguration.Active.TelemetryInitializers.Add(new CloudRoleNameTelemetryInitializer());
var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);
telemetryClient.TrackEvent(text);
}
Usando a classe TelemetryConfiguration inicializei a Rolename, configurei a classe TelemetryClient e com ela começo a logar informações por exemplo usando o método TrackEvent, tem algo parecido no onStop
protected override void OnStop()
{
var text = $"Service Stop At {DateTime.Now}";
var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);
telemetryClient.TrackEvent(text);
}
é isso mesmo, aqui eu sou responsável por definir os pontos da implementação onde quero guardar alguma informação, e para isso usei uma instância da classe TelemetryClient com o método TrackEvent
mas observei um trace estranho:
AI: error collecting 3 of the configured performance counters. Please check the configuration.
Ele não interfere na captura dos eventos, mas incomoda um pouco, olhando a documentação sobre application insights para console, percebo que o arquivo ApplicationInsights.config é muito mais simples e não precisa da tag a seguir.
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector">
...
</Add>
Basta comentá-la e o erro não será logado.
Também percebi que nenhum stop foi pego, então adicionei um sleep logo depois de enviar o TrackEvent do stop e um flush:
telemetryClient.Flush();
System.Threading.Thread.Sleep(1000);
Fiz um teste com uma aplicação console também, e segui a mesma linha do Windows Service, porém usei outro pacote:
Install-Package Microsoft.ApplicationInsights.WorkerService
aparentemente teve o mesmo efeito do windowsService, também criou o arquivo ApplicationInsights.config.
Fiz as mesmas inicializações que o windows services, mas coloquei um implementação para poder capturar requisições https.
static void Main(string[] args)
{
TelemetryConfiguration.Active.TelemetryInitializers.Add(new CloudRoleNameTelemetryInitializer());
var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);
telemetryClient.TrackTrace($"Start at {DateTime.Now} por TrackTrace");
telemetryClient.TrackEvent($"Start at {DateTime.Now} por TrackEvent");
var httpClient = new HttpClient();
using (telemetryClient.StartOperation<RequestTelemetry>("ConsoleAppI2"))
{
var res = httpClient.GetAsync("https://github.com/wilsonsantosnet").Result;
telemetryClient.TrackEvent("Chamada https://github.com/wilsonsantosnet pronta");
}
Console.Read();
}
O erro de coleta observado no windows service também ocorreu.
AI: Error collecting 3 of the configured performance counters. Please check the configuration.
Basta ajustar o arquivo ApplicationInsights.config conforme acima.
O Application Insights usa a classe HttpClient para enviar as informações para o Azure, mas em alguns casos as aplicações podem estar em uma intranet que não tem acesso a internet, por isso precisamos definir um proxy global na aplicação e assim o tráfego vai ser direcionado para esse endereço.
A questão é que o HttpClient funciona como uma faced, pode usar outras classes para fazer as chamadas de acordo com a plataforma.
Portanto em uma aplicação .NET Core usamos a seguinte configuração para globalmente configurar um proxy
var proxy = new WebProxy();
Configuration.Bind("DefaultProxy", proxy);
HttpClient.DefaultProxy = proxy;
..NET Core 2.x não permite configuração de proxy na aplicação exceto por código.
No entanto o método DefaultProxy não está disponível em uma aplicação Full Framework, mas como sabemos graças a documentação acima, por baixo dos panos a classe usada será a HttpWebRequest
Portanto podemos fazer algo assim em aplicações cuja classe HttpClient seja provida pelo Full Framework
var proxy = new WebProxy();
Configuration.Bind("DefaultProxy", proxy);
HttpWebRequest.DefaultWebProxy = proxy;
A partir do .NET Core 3.1 é possível configurar o proxy usando variáveis de ambiente.
Estas variáveis serão do tipo System, para que todos os processos em execução tenham acesso ao seu conteúdo, não somente o usuário logado. Outro ponto importante destacar é que das aplicações desenvolvidas com .NET Framework ou .NET Core, somente as com suporte ao .NET Core 3.X será influenciada por elas, as demais versões (exemplo versão 4.X ou versão anterior do .NET Core) não serão afetadas.
Também podemos apenas fazer essa configuração nos arquivos de configuração da aplicação de acordo com a plataforma;
"DefaultProxy": {
"Address": url,
"BypassProxyOnLocal": "true",
"BypassList": [
http://\*\\.dominio\\.subdominio\\.br/
]
}
<system.net>
<defaultProxy enabled="true" useDefaultCredentials="true">
<proxy proxyaddress="url" bypassonlocal="True" usesystemdefault="True"/>
<bypasslist>
<add address=".+\\.url.\*$"/>
</bypasslist>
</defaultProxy>
</system.net>
Uma dica que pode nos ajudar muito a entender o que esta acontecendo por baixo do capo é habilitar os logs do Application Insights, para isso basta alterar o ApplicationInsights.config
<TelemetryModules>
<Add Type="Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing.FileDiagnosticsTelemetryModule, Microsoft.ApplicationInsights">
<Severity>Verbose</Severity>
<LogFileName>mylog.txt</LogFileName>
<LogFilePath>C:\\\\SDKLOGS</LogFilePath>
</Add>
</TelemetryModules>
Podemos ver que no geral não é um processo de configuração complicado. Os benefícios de poder ver as informações de log em uma ferramenta centralizada e com diversos recursos que ajudam na análise, visualização e disponibilização dessas informações são enormes.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.