我已经更新了原始问题的内容,因为我开始在试图帮助我的人中引起一些混乱。
我正在使用库“Microsoft.ApplicationInsights.AspNetCore”将日志发送到 Azure。使用这个库的挑战之一是,在为库创建服务之前,它不会向 Azure 发送任何日志事件。
鸡和蛋的情况是,我需要在 Net Core 6 Web 应用程序的启动过程的最早阶段(即在实际创建 App Insights 需要运行的服务之前)编写日志并将它们发送到 Azure。
我需要在应用程序启动过程的早期阶段编写日志的原因是为了捕获用户登录的详细信息,其中 Microsoft 登录页面将在 .Net Core 应用程序启动后立即弹出。
在下面的代码示例中,您可以看到我创建了一个记录器工厂的实例,以便在构建和启动其余服务之前,我可以在 program.cs 文件中本地写入一些日志。尽管使用此方法可以写入控制台,但不会向 App Insights 发送任何事件。我认为这是因为 App 洞察库在创建所需服务之前尚未建立,该服务位于 program.cs 文件的后期阶段。
var builder = WebApplication.CreateBuilder(args);
// I create an instance of logger facroty
using var loggerFactory = LoggerFactory.Create(loggingBuilder => loggingBuilder
.SetMinimumLevel(LogLevel.Trace)
.AddConsole()
.AddApplicationInsights(builder.Configuration["APPINSIGHTS_CONNECTIONSTRING"]));
// I use the logger factory to create an instance of Ilogger
ILogger logger = loggerFactory.CreateLogger<Program>();
// This code section here is related to Microsoft Identity Web library and is responsible for
// triggering methods based upon when a user signs into Mirosoft (as well as signing out)
// When them methods are triggered in this service, i need to write logs and send them to Azure.
// The issue is this service runs before Application Insights service has been created/started, see code section below...
builder.Services.Configure<OpenIdConnectOptions>(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
// The claim in the Jwt token where App roles are available.
options.TokenValidationParameters.RoleClaimType = "roles";
// Advanced config - capturing user events. See OpenIdEvents class.
options.Events ??= new OpenIdConnectEvents();
options.Events.OnTokenValidated += openIdEvents.OnTokenValidatedFunc;
// This is event is fired when the user is redirected to the MS Signout Page (before they've physically signed out)
options.Events.OnRedirectToIdentityProviderForSignOut += openIdEvents.OnRedirectToIdentityProviderForSignOutFunc;
// DO NOT DELETE - May use in the future.
// OnSignedOutCallbackRedirect doesn't produce any user claims to read from for the user after they have signed out.
options.Events.OnSignedOutCallbackRedirect += openIdEvents.OnSignedOutCallbackRedirectFunc;
});
// --- IMPORTANT NOTE -----
This log event is succesfully written to the console, BUT it does not get sent to Azure App Insights.
// --------------------------------------------------------------------------------------
The methods triggered in the code section above by Microsoft Identity Web are actually stored in a seperate class,
// however being unbale to write a test log message here means that it wont work in a seperate class either.
logger.LogInformation("This is test message");
// ----- Other general servics being created required for my app -----
// Add the AuthorizationPolicies for the AppRoles
builder.Services.AddAuthorizationClaimPolicies();
builder.Services.AddAuthorization(options =>
{
// By default, all incoming requests will be authorized according to the default policy.
options.FallbackPolicy = options.DefaultPolicy;
});
builder.Services.AddRazorPages()
.AddMicrosoftIdentityUI();
// HERE IS THE PART WHERE APPLICATION INSIGHTS SERVICE IS CREATED,
// SO HAVING CREATED AN INSTANCE OF ILOGGER FACTORY BEFORE THIS STEP DOES NOT WORK
// ----- Configure Application Insights Telemetry -----
Microsoft.ApplicationInsights.AspNetCore.Extensions.ApplicationInsightsServiceOptions aiOptions = new();
aiOptions.ConnectionString = builder.Configuration["APPINSIGHTS_CONNECTIONSTRING"];
aiOptions.EnablePerformanceCounterCollectionModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnablePerformanceCounterCollectionModule");
aiOptions.EnableRequestTrackingTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableRequestTrackingTelemetryModule");
aiOptions.EnableEventCounterCollectionModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableEventCounterCollectionModule");
aiOptions.EnableDependencyTrackingTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableDependencyTrackingTelemetryModule");
aiOptions.EnableAppServicesHeartbeatTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAppServicesHeartbeatTelemetryModule");
aiOptions.EnableAzureInstanceMetadataTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAzureInstanceMetadataTelemetryModule");
aiOptions.EnableQuickPulseMetricStream = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableQuickPulseMetricStream");
aiOptions.EnableAdaptiveSampling = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableAdaptiveSampling");
aiOptions.EnableHeartbeat = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableHeartbeat");
aiOptions.AddAutoCollectedMetricExtractor = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("AddAutoCollectedMetricExtractor");
aiOptions.RequestCollectionOptions.TrackExceptions = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("RequestCollectionOptions.TrackExceptions");
aiOptions.EnableDiagnosticsTelemetryModule = builder.Configuration.GetSection("ApplicationInsights").GetValue<bool>("EnableDiagnosticsTelemetryModule");
// Build the serive with the options from above.
builder.Services.AddApplicationInsightsTelemetry(aiOptions);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
//app.MapControllers(); // Default mapping, not in use, see below...
app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();