Function App中自定义类无法向App Insights写入日志的问题排查
我正在开发一个自定义日志解决方案,需要同时将日志写入Azure Data Table和Application Insights。我创建了LogService类并通过依赖注入(DI)注入,供DataManager等类调用。计划在执行LogService.LogInformation方法时,先将日志写入App Insights,再通过Service Bus消息将日志插入Azure Data Table。
目前日志已成功写入Azure Data Table,但无法传入App Insights。我已确认配置了正确的APPINSIGHTS_INTRUMENTATIONKEY,并在Function App环境变量中设置了APPLICATIONINSIGHTS_CONNECTIONSTRING,同时安装了NuGet包:
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
请问还缺少什么配置才能让日志成功写入App Insights?
相关配置与代码如下:
Host.json
{ "version": "2.0", "functionTimeout": "-1", "logging": { "applicationInsights": { "samplingSettings": { "isEnabled": false, "excludedTypes": "Request" } }, "logLevel": { "Function": "Debug" } } }
Startup.cs
public override void Configure(IFunctionsHostBuilder builder) { //Add other dependencies here builder.Services.AddTransient<ILogService, LogService>(); builder.Services.AddTransient<IDataManager, DataManager>(); builder.Services.AddTransient<IAuditLogManager, AuditLogManager>(); builder.Services.AddTransient<IRecordManager, RecordManager>(); builder.Services.AddTransient<IUtilities, Utilities>(); builder.Services.AddTransient<IEmailManager, EmailManager>(); var connstring = Environment.GetEnvironmentVariable("DbConnection"); builder.Services.AddDbContext<DataContext>(options => { options.UseSqlServer(connstring, sqlServerOptions => { sqlServerOptions.CommandTimeout(180); sqlServerOptions.EnableRetryOnFailure(); }); options.EnableSensitiveDataLogging(); }); }
LogService.cs
public class LogService : ILogService { private readonly IConfiguration _config; private readonly ILogger<LogService> _log; //Use built in Logger service to send to App Insights. public LogService(IConfiguration config, ILogger<LogService> log) { _config = config; _log = log; } public void LogDebug(string message, string logType = "DEBUG") { LogInformation(message, logType); } public void LogError(string message, string logType = "ERROR") { LogInformation(message, logType); } public async void LogInformation(string message, string logType = "INFO") { //Log to built-in ILogger for App Insights and Mezmo if (logType.ToUpper().Contains("ERROR")) _log.LogError(message); if (logType.ToUpper().Contains("DEBUG")) _log.LogDebug(message); else _log.LogInformation(message); //Get time in CST and convert to the RowKey format. var cstDateTime = GetCurrentDateTimeCST(); var rowKey = cstDateTime.ToString("yyyyMMdd.HHmmssff"); string sbConnectionString = _config["LoggerURL"] ?? string.Empty; string sbQueue = _config["LogServiceBusQueue"] ?? string.Empty; var LoggingPartitionKey = _config["LoggingPartitionKey"] ?? string.Empty; // Create a Log Message and send to Service Bus var logEntity = new LogEntity(); logEntity.PartitionKey = LoggingPartitionKey; logEntity.RowKey = rowKey; logEntity.Message = message; logEntity.LogType = logType; //Serialize log object so be able to send in the message. var messageBody = JsonSerializer.Serialize(logEntity); try { ServiceBusClient serviceBusClient = new ServiceBusClient(sbConnectionString, new ServiceBusClientOptions() { TransportType = ServiceBusTransportType.AmqpWebSockets }); ServiceBusSender serviceBusSender = serviceBusClient.CreateSender(sbQueue); await serviceBusSender.SendMessageAsync(new ServiceBusMessage(messageBody)); } catch (Exception) { throw; } } public DateTime GetCurrentDateTimeCST() { DateTime cstDateTime = TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")); return cstDateTime; } }
你需要补充以下几个关键配置和代码调整,才能让日志成功写入Application Insights:
1. 注册Application Insights Worker服务
当前Startup.cs未将Application Insights集成到DI容器中,需在Configure方法内添加:
builder.Services.AddApplicationInsightsTelemetryWorkerService();
这一步会启用App Insights的日志收集能力,让ILogger实例能将日志推送到App Insights。
2. 调整Host.json日志级别配置
当前仅配置了Function命名空间的日志级别,需确保LogService所在命名空间的日志级别未被过滤。可添加全局默认级别或指定具体命名空间:
"logLevel": { "Function": "Debug", "Default": "Information", "YourNamespace.LogService": "Debug" // 替换为LogService实际所在的命名空间 }
如果LogService的日志级别高于你调用的方法级别(比如默认设为Warning,但你调用了LogInformation),日志会被系统过滤。
3. 修复异步方法的async void问题
LogInformation使用async void会导致日志可能在未完成发送时就被终止,Azure Functions环境下异步服务方法应返回Task:
public async Task LogInformation(string message, string logType = "INFO")
同时修改调用它的方法:
public async Task LogDebug(string message, string logType = "DEBUG") { await LogInformation(message, logType); } public async Task LogError(string message, string logType = "ERROR") { await LogInformation(message, logType); }
async void仅适用于事件处理程序,普通服务方法使用会引发上下文管理问题,导致日志无法正常发送。
4. 验证环境变量名称
确认App Insights连接字符串的环境变量名称为APPLICATIONINSIGHTS_CONNECTION_STRING(注意下划线),而非你当前设置的APPLICATIONINSIGHTS_CONNECTIONSTRING,名称错误会导致App Insights无法读取配置。
完成以上调整后,重新部署Function App,日志即可正常写入Application Insights。
内容的提问来源于stack exchange,提问作者Caverman

