2

我已经更新了原始问题的内容,因为我开始在试图帮助我的人中引起一些混乱。

我正在使用库“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();
4

3 回答 3

2

此代码使用 net 6 测试

var builder = WebApplication.CreateBuilder(args);

using var loggerFactory = LoggerFactory.Create(loggingBuilder => loggingBuilder
    .SetMinimumLevel(LogLevel.Trace)
    .AddConsole());

ILogger<LogTest> logger = loggerFactory.CreateLogger<LogTest>();
var test = new LogTest(logger);

或者你可以采用这个代码

var builder = WebApplication.CreateBuilder(args);

builder.Logging.ClearProviders();
 builder.Logging.AddConsole();
....

var app = builder.Build();

ILogger <LogTest> logger = app.Services.GetRequiredService<ILogger<LogTest>>();
var test = new LogTest(logger);

测试班

public class LogTest
    {
        private readonly ILogger<LogTest>  _logger;

         public LogTest(ILogger<LogTest> logger)
        {
            _logger = logger;  
            var message = $" LogTest logger created at {DateTime.UtcNow.ToLongTimeString()}";
            _logger.LogInformation(message);
        }
    }
于 2022-01-08T20:17:11.430 回答
1

您可以手动创建LoggerFactoryLogger

using var loggerFactory = LoggerFactory.Create(loggingBuilder => loggingBuilder
    .SetMinimumLevel(LogLevel.Trace)
    .AddConsole());

ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Example log message");

UPD

您需要复制适合您的“普通”设置。您可以尝试以下方法:

var configuration = new ConfigurationBuilder() // add all configuration sources used
    .AddJsonFile("appsettings.json", false, true)
    .AddEnvironmentVariables()
    .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", true, true)
    .Build();
using var loggerFactory = LoggerFactory.Create(loggingBuilder => loggingBuilder
    .AddConfiguration(configuration)
    .AddApplicationInsights());
// create logger and use it ....
于 2022-01-08T18:15:30.713 回答
1

正如您所发现的,在构建 DI 容器之前使用由 Azure Application Insights 支持的 ILogger 实际上不会将日志发送到 AppInsights。

由于 .NET 6 的新主机构建器确实通过 DI 支持巩固了从 Startup 类的迁移(实际上需要两个 DI 容器并且由于一些原因并不理想),因此没有很好的选择。从我所见,感觉微软不打算在开箱即用的启动期间支持复杂的日志记录提供程序。

也就是说,您可以尝试TelemetryClient使用检测密钥手动实例化 a 。从那里,您可以记录任何您想要的内容。像向您的事件自动添加属性等任何花哨的东西,很可能都不会起作用,因为没有真正设置任何东西。但是您应该能够将数据发送到您的 AppInsights。这尚未经过测试,但请尝试:

var client = new TelemetryClient(TelemetryConfiguration.CreateDefault());
client.InstrumentationKey = "YOUR_INSTRUMENTATION_KEY";
client.TrackTrace("Severe startup issue.", SeverityLevel.Critical);
于 2022-02-01T20:14:11.733 回答