после поднятия нашего проекта до .NET Standard 2.0 у нас возникла проблема с Nlog.
Кажется, что пользовательский метод Write()
не запускается.
У кого-нибудь из вас есть такая же проблема или идея, как ее решить?
зарегистрировать пользовательскую цель:
GlobalDiagnosticsContext.Set("configDir", Directory.GetCurrentDirectory());
ConfigurationItemFactory.Default.Targets.RegisterDefinition("DatabaseLog", typeof(MultiTenantDataBaseLogTarget));
var connectionString = Common.Lib.AppSettingsReader.GetConnectionString("DefaultConnection");
if (string.IsNullOrEmpty(connectionString)) // to support the .NET Framework Service DataProvider connectionString = ConfigurationManager.ConnectionStrings["localRuleContext"].ConnectionString;
LogManager.Configuration.Variables["connectionString"] = connectionString;
заказ цель:
using NLog;
using NLog.Common;
using NLog.Targets;
namespace OurNamespace.Logging
{
[Target("DatabaseLog")]
public class MultiTenantDataBaseLogTarget : DatabaseTarget
{
protected override void Write(AsyncLogEventInfo logEvent)
{
CommandText = $@"
insert into {logEvent.LogEvent.Properties["SchemaName"]}.ProtocolLogs (
Timestamp, LogLevel, MessageKey, Message, Parameters, [User], ApplicationName, Action, ObjectId, ObjectName
) values (
@Timestamp, @LogLevel, @MessageKey, @Message, @Parameters, @User, @ApplicationName, @Action, @ObjectId, @ObjectName
);";
base.Write(logEvent);
}
protected override void Write(LogEventInfo logEvent)
{
CommandText = $@"
insert into {logEvent.Properties["SchemaName"]}.ProtocolLogs (
Timestamp, LogLevel, MessageKey, Message, Parameters, [User], ApplicationName, Action, ObjectId, ObjectName
) values (
@Timestamp, @LogLevel, @MessageKey, @Message, @Parameters, @User, @ApplicationName, @Action, @ObjectId, @ObjectName
);";
base.Write(logEvent);
}
}
}
nlog.config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
throwExceptions="true"
autoReload="true"
internalLogLevel="Trace"
internalLogFile=".\Logs\internal-nlog.txt">
<extensions>
<add assembly="NLog.Targets.ElasticSearch"/>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<targets>
<target name="DatabaseLog" xsi:type="Database" >
<connectionString>${var:connectionstring}</connectionString>
<commandText>
insert into Schema.ProtocolLogs (
Timestamp, [LogLevel], MessageKey, Message, Parameters, [User], ApplicationName, Action, ObjectId
) values (
@Timestamp, @LogLevel, @MessageKey, @Message, @Parameters, @User, @ApplicationName, @Action, @ObjectId);
</commandText>
<parameter name="@Timestamp" layout="${event-properties:Timestamp:format=yyyy-MM-dd HH\:mm\:ss.fff}" />
<parameter name="@LogLevel" layout="${event-properties:LogLevel}" />
<parameter name="@MessageKey" layout="${event-properties:MessageKey}" />
<parameter name="@Message" layout="${message}" />
<parameter name="@Parameters" layout="${event-properties:Parameters}" />
<parameter name="@User" layout="${event-properties:User}" />
<parameter name="@ApplicationName" layout="${event-properties:ApplicationName}" />
<parameter name="@Action" layout="${event-properties:Action}" />
<parameter name="@ObjectId" layout="${event-properties:ObjectId}" />
<parameter name="@ObjectName" layout="${event-properties:ObjectName}" />
</target>
</targets>
<rules>
<logger name="DatabaseLog" minlevel="Trace" writeTo="DatabaseLog" />
</rules>
</nlog>
И вот как мы делаем лог-вызов:
var theEvent = new LogEventInfo(nLogLevel, logFilterName, message);
theEvent.Properties["SchemaName"] = _schemaTarget;
// more properties added...
var logger = LogManager.GetLogger("DatabaseLog");
logger.Log(theEvent)
В Framework 4.5 этот код работал так, как нам нужно.
Теперь похоже, что logger.Log(theEvent)
просто напишите непосредственно в базу данных, пропустив наш пользовательский метод.