我正在尝试实现一个自定义记录器,将日志从 azure webjob 发送到 azure eventhub,但无法使其工作。有没有比使用自定义记录器更简单的方法? 我尝试编写自己的解决方案,该解决方案与我在 github 上找到的解决方案几乎相同。 https://github.com/UKHO/EventHub-Logging-Provider/tree/main/UKHO.Logging.EventHubLogProvider
如果我在 .net 中的简单 webapi 上实现它,该解决方案效果很好,但在 azure webjob 上实现它时,如果在启动期间调用自定义记录器“Log”函数时失败并出现 stackoverflow 异常。我猜想 azure sdk 的功能与 webapi 不同...是否有一种方法可以仅在来自特定名称空间或其他内容的类上初始化自定义记录器?
public class CustomLogger : ILogger
{
private readonly string componentName;
private readonly string environment;
private readonly string machineName;
private readonly EventHubBufferedProducerClient eventHubBufferedProducerClient;
public CustomLogger(string componentName, string environment, string machineName, EventHubBufferedProducerClient eventHubBufferedProducerClient)
{
this.componentName = componentName;
this.environment = environment;
this.machineName = machineName;
this.eventHubBufferedProducerClient = eventHubBufferedProducerClient;
}
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
{
return default!;
}
public bool IsEnabled(LogLevel logLevel)
{
return !string.IsNullOrEmpty(componentName);
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
var logEvent = new LogEvent
{
Component = this.componentName,
Level = logLevel.ToString(),
Host = this.machineName,
Environment = this.environment,
Message = formatter(state, exception),
Exception = exception?.ToString()
};
this.eventHubBufferedProducerClient.EnqueueEventAsync(new EventData(System.Text.Json.JsonSerializer.Serialize(logEvent))).Wait();
}
}
这是我创建自定义记录器以将日志从 Azure WebJob 发送到 Azure 事件中心的方法。 确保正确初始化和处置资源。
using System;
using Microsoft.Extensions.Logging;
public class EventHubLogger : ILogger
{
private readonly string _eventHubConnectionString;
private readonly string _eventHubName;
public EventHubLogger(string eventHubConnectionString, string eventHubName)
{
_eventHubConnectionString = eventHubConnectionString;
_eventHubName = eventHubName;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true; // Implement your log level filtering logic here
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
string logMessage = formatter(state, exception);
}
}
using Microsoft.Extensions.Logging;
public class EventHubLoggerProvider : ILoggerProvider
{
private readonly string _eventHubConnectionString;
private readonly string _eventHubName;
public EventHubLoggerProvider(string eventHubConnectionString, string eventHubName)
{
_eventHubConnectionString = eventHubConnectionString;
_eventHubName = eventHubName;
}
public ILogger CreateLogger(string categoryName)
{
return new EventHubLogger(_eventHubConnectionString, _eventHubName);
}
public void Dispose()
{
// Dispose of any resources if needed
}
}
using Microsoft.Extensions.Logging;
using System;
class Program
{
static void Main()
{
string eventHubConnectionString = "your_eventhub_connection_string";
string eventHubName = "your_eventhub_name";
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddProvider(new EventHubLoggerProvider(eventHubConnectionString, eventHubName));
});
ILogger logger = loggerFactory.CreateLogger("MyCustomLoggerCategory");
logger.LogInformation("This is a log message.");
// Run your WebJob logic here
// ...
Console.WriteLine("Azure WebJob has completed.");
// You might want to wait for user input to keep the console window open, depending on your deployment method
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
结果
控制台
EventHub 中的请求