首页 > 解决方案 > NLog 自定义目标在 Azure .NET Core 2.1 中失败

问题描述

我一直在使用 NLog 和 .NET Core 2.0 和一个自定义目标来成功写入 Azure Blob 存储一段时间。

我现在已经升级到 .NET Core 2.1 并且部署到 Azure Web 应用程序的解决方案失败了,因为根据 Kudu 事件日志,NLog 找不到 NLog 配置文件中定义的自定义目标,尽管它似乎在本地工作得很好.

我的主机生成器如下:

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseUnityServiceProvider()
            .UseNLog()
            .UseStartup<Startup>();

我的 NLog 目标是在启动类中定义的:

        public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", false, true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", true)
            .AddJsonFile("appsettings.local.json", true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
        HostingEnvironment = env;

        NLogRegistry.Register(env, new ConfigurationAdapter(Configuration));
    }

NLog Registry 只是基于自定义目标的解决方案的包装器,该解决方案为带有 .net 核心的 NLog 注入服务

IE

    public class NLogRegistry
{
    public static void Register(IHostingEnvironment env, IConfigurationAdapter configuration)
    {
        //Setup custom NLog Azure Blob logger with injected configuration
        Target.Register<AzureBlobStorageTarget>("AzureBlobStorage");

        var nlog = ConfigurationItemFactory.Default.CreateInstance;
        ConfigurationItemFactory.Default.CreateInstance = type =>
        {
            try
            {
                return nlog(type);
            }
            catch (Exception)
            {
            }

            return new AzureBlobStorageTarget(configuration);
        };

        env.ConfigureNLog("nlog.config");
    }
}

我认为正在发生的是 .NET Core 管道的行为发生了一些变化,因此 NLog 在 Startup 方法之前被调用。由于 NLog 配置为“自动发现”nlog.config,它会在我有机会正确配置目标之前尝试设置。

如果我重命名 nlog.config 文件,则不会发生自动发现,并且 NLog 必须等到我在注册类中运行 ConfigureNLog 方法。然后,一切正常。

有谁知道 Azure 调用的 ASP.NET Core 2.1 管道中的正确位置是确保我可以在 NLog 尝试自动配置之前正确配置 NLog 目标?

标签: azurenlogasp.net-core-2.1

解决方案


无需将IConfiguration构造函数注入到 AzureBlobStorageTarget,您现在只需将 NLog Layout-Type 用于 AzureBlobStorageTarget-properties。

然后${configsetting}使用 NLog.Extension.Logging 版本配置布局。1.4.0:

https://github.com/NLog/NLog/wiki/ConfigSetting-Layout-Renderer

也许也可以考虑改为这个 NLog 目标:

https://github.com/JDetmar/NLog.Extensions.AzureStorage#blob-configuration

但是如果你坚持使用依赖于构造函数参数的依赖注入的自定义目标:

https://github.com/NLog/NLog/wiki/Dependency-injection-with-NLog


推荐阅读