#c# #nlog #asp.net-core-3.1
Вопрос:
У меня есть nlog.config
настройка файла с целевой базой данных, и я хочу прочитать строку подключения из appsettings.json
(и для всех, кому это интересно, значение in appsettings
на самом деле хранится в Azure KeyVault). Как правильно это сделать? У меня есть ASP.NET основное приложение 3.1.
nlog.config
<?xml version="1.0" encoding="utf-8" ?>
<!--The first nLog section internal log file logs the NLog configuration issues, Don't remove this-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="debug"
internalLogFile="c:tempfoo.txt">
<extensions>
<add assembly="NLog.Extensions.Logging"/>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<variable name="defaultLayout" value="${date} ${threadid} ${uppercase:${level}} ${logger} ${ndc} - ${message}${newline}" />
<variable name="logDirectory" value="./logs/${shortdate}"/>
<variable name="apiFileLogPath" value="c:tempapi-nlog.txt"/>
<!-- the targets to write to -->
<targets>
<target name="dbTarget"
xsi:type="Database"
commandText="..."
connectionString="${configsetting:item=NLogConfiguration.ConnectionString}">
<!--<connectionString></connectionString>-->
</target>
<!-- write to the void aka just remove -->
<target xsi:type="Null" name="blackhole" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--Skip Microsoft logs and so log only own logs-->
<!--<logger name="*" minlevel="Trace" writeTo="blackhole" final="true" />-->
<logger name="*" minlevel="Debug" writeTo="dbTarget" />
</rules>
</nlog>
Соответствующая часть appsettings.json
файла:
{
"NLogConfiguration": {
"ConnectionString": "..."
}
}
У меня в коде есть точка останова для проверки целевого объекта базы данных, но значение строки подключения не устанавливается. он остается таким же ${configsetting:item=NLogConfiguration.ConnectionString}
У меня нет никакого кода NLog при запуске. У меня есть класс-оболочка вокруг NLog, и я инициализирую его таким образом. Этот класс показан ниже:
DBLogManager
using System;
using System.Configuration;
using System.Globalization;
using System.Web;
using NLog;
using System.Xml;
using System.IO;
using System.Reflection;
using System.Text;
using Microsoft.Extensions.Configuration;
namespace DBLog.DBLogManager
{
public class DBLogManager : IDBLogManager
{
static ILogger InitializeDBLogManager()
{
XmlDocument nLogConfig = new XmlDocument();
var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "nlog.config");
NLog.LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(path);
return LogManager.GetLogger("AppLogger");
}
private static readonly ILogger Logger = InitializeDBLogManager();
}
}
Комментарии:
1. В вашей конфигурации есть ошибка XML
internalLogFile="c:tempfoo.txt>
. Это ошибка с копипастом? (отсутствует цитата)2. @Julian да ошибка копирования-вставки. Спасибо. Я обновил его.
3. @Bmoe Может также включать код, который инициализирует Хост и фактически загружает настройки приложений, поскольку NLog нуждается в небольшой помощи для доступа к настройкам приложений с хоста.
Ответ №1:
Я бы изменил DBLogManager
на это:
namespace DBLog.DBLogManager
{
public class DBLogManager : IDBLogManager
{
// NLog will automatically load NLog.config from AppDomain.BaseDirectory
private static readonly NLog.Logger Logger = NLog.LogManager.GetLogger("AppLogger");
}
}
И просто добавьте UseNLog()
вот так:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseNLog();
Если вы хотите, чтобы регистратор NLog был создан до IHostBuilder, сделайте это (вместо NLogBuilder.ConfigureNLog
):
var logger = LogManager.Setup()
.LoadConfigurationFromAppSettings()
.GetCurrentClassLogger();
Комментарии:
1. Ответ Джулиана действительно помог и был раньше вашего. Мне просто нужно было собрать все воедино. Спасибо.
2. @bmoe Да, никаких проблем. Я просто хотел подчеркнуть, что код, включенный в
DBLogManager
него, был ненужным.3. Я думаю, что этот ответ лучше, так что не стесняйтесь отмечать как ответ 🙂
Ответ №2:
Для ${configsetting}
вас нужен хотя бы пакет NLog.Расширения.Ведение журнала или один из зависимых пакетов, таких как NLog.Web.AspNetCore или NLog.Расширения.Принимающий.
Обычно вы использовали .UseNLog()
бы на IHostBuilder
, см. NLog — Начало работы с ASP.NET Ядро 3
Чтобы вручную зарегистрировать расширение Microsoft IConfiguration
с помощью ${configsetting}
:
IConfigurationRoot config = new ConfigurationBuilder()
.AddJsonFile(path: "AppSettings.json").Build();
NLog.Extensions.Logging.ConfigSettingLayoutRenderer.DefaultConfiguration = config;
См. раздел Визуализатор компоновки NLog — Настройка конфигурации
Комментарии:
1.
AddJsonFile
Требуется ли линия? У меня этого нет, но мое приложение все еще может считыватьappsettings.json
файлы.2. Я не голосовал против, но предполагаю, что это потому, что вы просто повторно использовали существующую документацию, которую, по-видимому, люди не поняли в первую очередь. Я предполагаю, что было ожидание, что вы предоставите рабочий образец. Строки кода, которые вы опубликовали, я лично не знал бы, куда они ведут, если бы раньше не работал с кодом запуска.
3. Вам нужно назначить
NLog.Extensions.Logging.ConfigSettingLayoutRenderer.DefaultConfiguration
. Вы также можете разрешить конфигурацию в зависимости от остальной части вашего кода