C# 如何将Serilog与Azure WebJobs一起使用?

C# 如何将Serilog与Azure WebJobs一起使用?,c#,.net,azure,azure-webjobs,serilog,C#,.net,Azure,Azure Webjobs,Serilog,我正在尝试使用Serilog设置Azure WebJobs。以下是我目前的例外情况: Microsoft.Azure.WebJobs.Host.Indexers.FunctionIndexingException: 索引方法“Functions.ProcessQueueMessage”时出错 --->System.InvalidOperationException:无法将参数“logger”绑定到类型ILogger。确保参数类型受 结合如果您使用的是绑定扩展(例如Azure存储、, 服务总线、计

我正在尝试使用Serilog设置Azure WebJobs。以下是我目前的例外情况:

Microsoft.Azure.WebJobs.Host.Indexers.FunctionIndexingException: 索引方法“Functions.ProcessQueueMessage”时出错 --->System.InvalidOperationException:无法将参数“logger”绑定到类型ILogger。确保参数类型受 结合如果您使用的是绑定扩展(例如Azure存储、, 服务总线、计时器等)确保您已拨打注册电话 启动代码中扩展名的方法(例如。 builder.AddAzureStorage(),builder.AddServiceBus(), builder.AddTimers()等)

我看到了,但是Serilog.Extensions.WebJobs不再维护

我尝试了的变体,但它要么导致相同的异常,要么不使用队列消息

我也尝试过,但我不知道在哪里可以找到SDK依赖项的最终列表,以取消选中任何潜在的版本控制不匹配

当ProcessQueueMessage使用
Microsoft.Extensions.Logging.ILogger
但不使用
Serilog.ILogger
时,以下功能将按预期工作:

class Program
{
    static async Task Main()
    {
        var builder = new HostBuilder();
        builder.UseSerilog();
        builder.ConfigureWebJobs(b =>
        {
            b.AddAzureStorageCoreServices();
            b.AddAzureStorage();
        });
        var host = builder.Build();
        try { await host.RunAsync(); }
        catch (Exception ex) { Log.Logger.Fatal(ex.Message, ex); }
    }
}

public class Functions
{
    public static void ProcessQueueMessage([QueueTrigger("queue")] string message, ILogger logger)
    {
        logger.Information(message); // Serilog ILogger
    }
}
项目包参考:


(也与预发布一起播放)


将ILogger作为一个函数参数,就像一个符咒一样工作

Serilog.Extensions.WebJobs的作者提供了一个合适的解决方案,我将其浓缩如下:

class Program
{
    static async Task Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.Console()
            .CreateLogger();

        IHostBuilder builder = Host.CreateDefaultBuilder(args)
            .UseSerilog(Log.Logger)
            .ConfigureServices(s => s.AddSingleton(Log.Logger))
            .ConfigureWebJobs(b =>
            {
                b.AddAzureStorageCoreServices();
                b.AddAzureStorage();
                b.AddTimers();
            });

        IHost host = builder.Build();
        try { await host.RunAsync(); }
        catch (Exception ex) { Log.Fatal(ex.Message, ex); }
        finally { Log.CloseAndFlush(); }
    }
}

public class Functions
{
    readonly ILogger _logger;

    public Functions(ILogger logger) => _logger = logger.ForContext<Functions>();

    public void ProcessQueueMessage([QueueTrigger("queue")] string message) =>
        _logger.Information(message);
}
类程序
{
静态异步任务主(字符串[]args)
{
Logger.Logger=新的LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.CreateLogger();
IHostBuilder=Host.CreateDefaultBuilder(args)
.useserlog(Log.Logger)
.ConfigureServices(s=>s.AddSingleton(Log.Logger))
.ConfigureWebJobs(b=>
{
b、 AddAzureStorageCoreServices();
b、 AddAzureStorage();
b、 AddTimers();
});
IHost host=builder.Build();
请尝试{wait host.RunAsync();}
catch(异常ex){Log.Fatal(ex.Message,ex);}
最后{Log.CloseAndFlush();}
}
}
公共类功能
{
只读ILogger\u记录器;
公共函数(ILogger logger)=>\u logger=logger.ForContext();
public void ProcessQueueMessage([QueueTrigger(“queue”)]string message)=>
_记录器信息(消息);
}
包参考:





信用:@James Skiming

当它失败时,在您的ProcessQueueMessage上,ILogger是什么类型的?是Microsoft.Extensions.Logging.ILogger还是Serilog.ILogger?我可能误解了你的问题,但它没有类型,因为它无法绑定,所以它没有达到ProcessQueueMessage的程度,因此无法确保它有类型。你得到了一个运行时错误,但我甚至没有谈论运行时。我说的是在编译时。当您将鼠标悬停在该方法参数中的ILogger上时,它声明为什么名称空间?啊,编译时:SerilogIm不完全确定UseSerilog()的作用,但它可能会将其连接起来,以便在您使用Microsoft.Extensions.Logging.ILogger时,它最终将这些名称空间写入Serilog。它可能不一定为Serilog自己的ILogger连接DI。我以前从未编写过WebJob,但我怀疑您可以将ProcessQueueMessage切换为依赖于Microsoft.Extensions.Logging.ILogger,或者取消UseSerilog(),而是手动创建Serilog ILogger并向DI容器注册。或者,您可以将方法更改为根本不接受ILogger,而只接受静态日志方法