Пользовательская цель NLog не работает в Azure .NET Core 2.1

Некоторое время я успешно использовал NLog с .NET Core 2.0 и настраиваемую цель для записи в хранилище BLOB-объектов Azure.

Теперь я обновился до .NET Core 2.1, и развернутое решение для веб-приложения Azure не удается, потому что, согласно журналу событий 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 - это просто оболочка для решения, основанного на Настраиваемая цель с внедренными службами для NLog с ядром .NET

i.e.

    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 в моем классе регистров. Тогда все работает нормально.

Кто-нибудь знает, какое правильное место в конвейере ASP.NET Core 2.1, вызываемом Azure, - это убедиться, что я могу правильно настроить цель NLog, прежде чем NLog попытается выполнить автонастройку?


person GrahamB    schedule 27.06.2018    source источник
comment
NLog пытается настроить себя, как только вы создаете первый объект Logger (также включает статические объекты Logger при инициализации класса). Может быть, какая-то структура внедрения зависимостей запускает некоторые инициализаторы статических классов?   -  person Rolf Kristensen    schedule 28.06.2018
comment
@RolfKristensen Я думаю, это имеет смысл, мне интересно, что изменилось в конвейере .NET Core 2.1, чтобы вызвать это.   -  person GrahamB    schedule 29.06.2018


Ответы (1)


Вместо того, чтобы вставлять IConfiguration в конструктор в свой AzureBlobStorageTarget, теперь вы можете просто использовать NLog Layout-Type для свойств AzureBlobStorageTarget.

Затем настройте макет с помощью ${configsetting}, представленного с помощью NLog.Extension.Logging ver. 1.4.0:

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

Возможно, также подумайте о переходе на этот NLog-target вместо этого:

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

Но если вы настаиваете на использовании настраиваемой цели, которая полагается на внедрение зависимостей параметров конструктора:

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

person Rolf Kristensen    schedule 02.02.2019