W jednym z moich ostatnich artykułów (Application Insights – Ukryty Skarb Azure) przeszliśmy przez podstawową konfigurację usługi application insights oraz bardzo podstawową integrację. Jako, że obiecałem wam więcej treści z tematu, tak oto powstał ten artykuł. Zajmiemy się wprowadzeniem integracji z Application Insights na kolejny poziom. Jako, że to kontynuacja, bardzo zachęcam abyś przeczytał wcześniejszy artykuł.
SeriLog
Zacznijmy od rzeczy podstawowej. Jak przy większości moich projektów zaczynam od dogrania i skonfigurowania biblioteki wspomagającej semantyczne logowanie. W moim przypadku jest to SeriLog. Jeżeli korzystasz z np. Log4Net, nie ma czym się przejmować. Dopóki Twoja biblioteka bazuje na interfejsie ILogger
wszystko powinno być w porządku.
Oczywiście, jak to w świecie .NET-a, aby zacząć używać gotowej paczki, musimy ją pobrać do projektu za pomocą nuget-a. Paczka nazwy się Serilog.AspNetCore
.
Następnie należy, w pliku Program.cs
, utworzyć konfigurację logger-a. Ja to robię w następujący sposób:
public class Program { public static void Main(string[] args) { var configuration = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft", LogEventLevel.Verbose) .MinimumLevel.Override("System", LogEventLevel.Verbose) .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Verbose) .Enrich.FromLogContext() .Enrich.WithProperty("ApplicationName", typeof(Program).Assembly.GetName().Name) .WriteTo .Console(); Log.Logger = configuration.CreateLogger(); try { Log.Information("Starting Up"); CreateHostBuilder(args).Build().Run(); } catch (Exception e) { Log.Fatal(e, "Application startup failed"); } finally { Log.CloseAndFlush(); } } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }) .UseSerilog(); }
Pewnie zastanawiasz się dlaczego w liniach 7-10 ustawiłem minimalny poziom logowania na Verbose
. Jest to jak najbardziej świadomy i celowy zabieg. Jako, że obecnie dodajemy wszystko na pustym projekcie, wysoki poziom szczegółowości logów pomoże zapełnić usługę application insights. W produkcyjnej aplikacji nie radziłbym go stosować. Czasami zbyt duża liczba logów generuje niepotrzebny szum informacyjny i ciężej znaleźć istotne elementy.
W tym miejscu przydałoby się omówić jeszcze jedną kwestię, mianowicie ulokowanie tego kodu w pliku Program.cs
. Wiem, że często spotykaną praktyką jest konfiguracja logger-a w pliku Startup.cs
. Mamy tam dostęp do całej konfiguracji znajdującej się w pliku appsettings.json
co pozwala nam na uniknięcie problemu typu “kury i jajka”. Na szczęście jest łatwy do rozwiązania za pomocą np. zmiennych środowiskowych, dzięki czemu uzyskamy logi z startu aplikacji. Dlatego podejście zaprezentowane wyżej jest, przynajmniej moim odczuciu, zdecydowanie lepsze.
Integracja logów i Application Insights
Kolejnym krokiem, który musisz wykonać, jest skonfigurowanie sdk Application Insights w taki sposób, aby zapisywało logi w swojej usłudze. Kiedyś zadanie było dużo prostsze, wystarczyła pomoc biblioteki Serilog.Sinks.ApplicationInsights. Czas jednak mija i wiele się zmienia. Podczas próby wykorzystania kodu znajdującego się w przykładzie tej biblioteki zobaczysz, że TelemetryConfiguration.Active
jest już oznaczone jako depracted
i nie powinieneś opierać swojej implementacji na tym polu statycznym.
Aby zintegrować logi z Application Insights będziesz musiał dograć jeszcze jedną paczkę nuget-a – Microsoft.Extensions.Logging.ApplicationInsights
, która doda swoją implementacje interfejsu ILogger
. Następnie będziesz musiał wrócić do pliku Startup.cs
i dodać konfigurację przedstawioną poniżej:
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }) .UseSerilog() .ConfigureLogging(builder => { builder.AddApplicationInsights("InstrumentationKey"); });
Cloud Role i Cloud Instance
Ostatnimi elementami, jakie chce poruszyć, są Cloud Role Name
i Cloud Role Instance
.
Cloud Role Name
to nazwa procesu. Może to być nazwa naszej aplikacji, serwisu etc. Jest wykorzystywany np. w panelu ApplicationMap
, aby dokonać wizualizacji przepływu informacji pomiędzy procesami.
Uważam to za szczególnie przydatne, tym bardziej w momencie, kiedy mamy więcej procesów, jak np. Frontend i Backend czy też środowisko mikroserwisowe. W momencie kiedy ta wartość nie jest ustawiona, Application Insights będzie robiło wszystko co w jego mocy, aby nazwać ten proces (np. może użyć nazwy aplikacji jeżeli aplikacja będzie uruchomiona w Azure App Service).
Natomiast Cloud Role Instance
powinno zawierać informację na jakiej instancji procesu Cloud Role Name
działa. Jest to bardzo ważne w momencie, kiedy próbujemy skalować naszą aplikację. Np. gdybyś spróbował zwiększyć liczbę instancji swojej aplikacji i wystawił ją na świat za load balancerem prawdopodobnie chciałbyś mieć informacje, na jakiej instancji występują błędy. Dlatego możemy nadać identyfikator naszej instancji np. “My_Api_Prod_1”.
Wymaga to dodania własnej implementacji interfejsu ITelemetryInitializer
gdzie w metodzie Initialize
możesz ustawić wszystkie wartości.
public class ApiTelemetryInitializer : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { if (string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName)) { telemetry.Context.Cloud.RoleName = "My.Api"; telemetry.Context.Cloud.RoleInstance = "My_Api_Prod_1"; } } }
Na koniec trzeba powrócić do pliku Startup.cs
, aby zarejestrować utworzoną klasę w kontenerze DI.
public void ConfigureServices(IServiceCollection services) { services.AddSingleton<ITelemetryInitializer, ApiTelemetryInitializer>(); services.AddApplicationInsightsTelemetry(); // ... }
Podsumowanie
To by było na tyle, konfiguracja powinna śmigać i wyglądać całkiem składnie. W następnym artykule zagłębimy się w panel usługi Application Insights, aby zobaczyć jakie możliwości oferuje.
Jak zwykle mam nadzieje że artykuł się podobał!
Do Następnego!
PS. Spodobał Ci się ten artykuł?
Referencje
https://docs.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview