NLog: Как добавить 2 разные цели и правила базы данных в одной конфигурации? - PullRequest
0 голосов
/ 12 февраля 2020

Я изучал, как программно добавить несколько целей базы данных. Мне нужно только 2, и я не могу понять, как заставить их работать.

Я могу заставить работать только 1 цель и регистратор. Например, работают 2 блока кода ниже:

Мой код конфигурации (1 цель):

    var config = new LoggingConfiguration();
    // Add another NLog Target (ChangeTracking)
    var changeTrackingDbTarget = new DatabaseTarget()
    {
        Name = "ChangeTracking",
        ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["NLogConnection"].ConnectionString,
        CommandText = "INSERT INTO Common.ChangeTracking (ApplicationID, UserName, EntityName, PropertyName, PrimaryKeyValue, OldValue, NewValue, DateChanged) " +
                      "VALUES (@ApplicationID, @UserName, @EntityName, @PropertyName, @PrimaryKeyValue, @OldValue, @NewValue, @DateChanged);"
    };

    changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@ApplicationID", Layout = "${appsetting:name=AppID:default=null}" });
    changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@UserName", Layout = "${identity:authType=false:isAuthenticated=false}" });
    changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@EntityName", Layout = "${event-properties:item=ENTITYNAME}" });
    changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@PropertyName", Layout = "${event-properties:item=PROPNAME}" });
    changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@PrimaryKeyValue", Layout = "${event-properties:item=PRIMARYKEY}" });
    changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@OldValue", Layout = "${event-properties:item=OLDVALUE}" });
    changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@NewValue", Layout = "${event-properties:item=NEWVALUE}" });
    changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@DateChanged", Layout = "${date}" });

    config.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, changeTrackingDbTarget));

    //LogManager.Configuration.AddTarget("ExceptionTracking", dbTarget);
    LogManager.Configuration = config;

Мой код, который вызывает журналы (1 цель):

private static Logger _logger = LogManager.GetLogger("ChangeTracking");
                        LogEventInfo changeEvent = new LogEventInfo(LogLevel.Info, "ChangeTracking", "A change event has been fired");
                        changeEvent.Properties["ENTITYNAME"] = entityName;
                        changeEvent.Properties["PROPNAME"] = prop;
                        changeEvent.Properties["PRIMARYKEY"] = primaryKey;
                        changeEvent.Properties["OLDVALUE"] = originalValueString;
                        changeEvent.Properties["NEWVALUE"] = currentValueString;
                        _logger.Log(changeEvent);

Мой код конфигурации (2 цели):

    // Setup NLOG Database Target for Exception Tracking
    LogManager.ThrowExceptions = true;
    var dbTargetExceptions = new DatabaseTarget()
    {
        Name = "ExceptionTracking",
        ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["NLogConnection"].ConnectionString,
        CommandText = "INSERT INTO Common.ExceptionTracking ( ApplicationID,  Url,  IP,  Referrer,  UserName,  ExceptionDescription,  Action,  Controller,  InsertedBy,  InsertedDate) " +
                                                    "VALUES (@ApplicationID, @Url, @IP, @Referrer, @UserName, @ExceptionDescription, @Action, @Controller, @InsertedBy, @InsertedDate);"
    };
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@ApplicationID", Layout = "${appsetting:name=AppID:default=null}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@Url", Layout = "${aspnet-Request-Url}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@IP", Layout = "${aspnet-Request-IP}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@Referrer", Layout = "${aspnet-Request-Referrer}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@UserName", Layout = "${identity:authType=false:isAuthenticated=false}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@ExceptionDescription", Layout = "${exception:tostring}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@Action", Layout = "${aspnet-MVC-Action}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@Controller", Layout = "${aspnet-MVC-Controller}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@InsertedBy", Layout = "${gdc:BEMSID}" });
    dbTargetExceptions.Parameters.Add(new DatabaseParameterInfo() { Name = "@InsertedDate", Layout = "${date}" });

    // Setup NLOG Database Target for Change Tracking
        var changeTrackingDbTarget = new DatabaseTarget()
        {
            Name = "ChangeTracking",
            ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["NLogConnection"].ConnectionString,
            CommandText = "INSERT INTO Common.ChangeTracking (ApplicationID, UserName, EntityName, PropertyName, PrimaryKeyValue, OldValue, NewValue, DateChanged) " +
                          "VALUES (@ApplicationID, @UserName, @EntityName, @PropertyName, @PrimaryKeyValue, @OldValue, @NewValue, @DateChanged);"
        };

        changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@ApplicationID", Layout = "${appsetting:name=AppID:default=null}" });
        changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@UserName", Layout = "${identity:authType=false:isAuthenticated=false}" });
        changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@EntityName", Layout = "${event-properties:item=ENTITYNAME}" });
        changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@PropertyName", Layout = "${event-properties:item=PROPNAME}" });
        changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@PrimaryKeyValue", Layout = "${event-properties:item=PRIMARYKEY}" });
        changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@OldValue", Layout = "${event-properties:item=OLDVALUE}" });
        changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@NewValue", Layout = "${event-properties:item=NEWVALUE}" });
        changeTrackingDbTarget.Parameters.Add(new DatabaseParameterInfo() { Name = "@DateChanged", Layout = "${date}" });

    //Setup NLOG Configuration. Adding DB Targets and Rules for Targets
    LoggingConfiguration nLogConfig = new LoggingConfiguration();
    nLogConfig.AddTarget("ExceptionTracking", dbTargetExceptions);
    nLogConfig.AddTarget("ChangeTracking", dbTargetChanges);
    nLogConfig.LoggingRules.Add(new LoggingRule("ChangeLogger", LogLevel.Info, dbTargetChanges));
    nLogConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, dbTargetExceptions));

    //Finally set the configuration above to the LogManager config property
    LogManager.Configuration = nLogConfig;

Мой код, который вызывает журнал (2 цели):

 private static Logger _logger = LogManager.GetLogger("ChangeTracking");
                        LogEventInfo changeEvent = new LogEventInfo(LogLevel.Info, "ChangeTracking", "A change event has been fired");
                        changeEvent.Properties["ENTITYNAME"] = entityName;
                        changeEvent.Properties["PROPNAME"] = prop;
                        changeEvent.Properties["PRIMARYKEY"] = primaryKey;
                        changeEvent.Properties["OLDVALUE"] = originalValueString;
                        changeEvent.Properties["NEWVALUE"] = currentValueString;
                        _logger.Log(changeEvent);

1 Ответ

2 голосов
/ 13 февраля 2020

Ваш конфиг правильный. AddTarget на самом деле не является необходимым, так как вы передаете Target правилу, и Target имеет то же свойство name. Так что этого должно быть достаточно:

LoggingConfiguration nLogConfig = new LoggingConfiguration();
nLogConfig.LoggingRules.Add(new LoggingRule("ChangeLogger", LogLevel.Info, dbTargetChanges));
nLogConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, dbTargetExceptions));

//Finally set the configuration above to the LogManager config property
LogManager.Configuration = nLogConfig;

Я лично предпочитаю AddRule на LoggingConfiguration. Это то же самое, что и выше, но AddRule -стиль:

LoggingConfiguration nLogConfig = new LoggingConfiguration();
nLogConfig.AddRule(LogLevel.Info, LogLevel.Fatal, dbTargetChanges, "ChangeLogger");
nLogConfig.AddRule(LogLevel.Trace, LogLevel.Fatal, dbTargetExceptions);

//Finally set the configuration above to the LogManager config property
LogManager.Configuration = nLogConfig;

Если это не сработает в ваших изменениях, включите и проверьте внутренний журнал на уровне трассировки.

и другие, которые я хочу вызывать по умолчанию везде, где бы то ни было

Обратите внимание, что правила обрабатываются сверху вниз и остановятся, только если вы добавите "final" (или условие, которое не будет совпадать).

Так что для вышеуказанного конфига запись в «ChangeLogger» запишет в обе цели. Я не уверен, что это то, что вам нужно. Если нет, то:

  • Или добавьте Final = true к первому правилу

    // Old style
    nLogConfig.LoggingRules.Add(new LoggingRule("ChangeLogger", LogLevel.Info, dbTargetChanges){Final = true});
    nLogConfig.LoggingRules.Add(new LoggingRule("*", LogLevel.Trace, dbTargetExceptions));
    // Or AddRule style:
    nLogConfig.AddRule(LogLevel.Info, LogLevel.Fatal, dbTargetChanges, "ChangeLogger", true);  
    nLogConfig.AddRule(LogLevel.Trace, LogLevel.Fatal, dbTargetExceptions);
    
  • Или добавьте условие / фильтр ко 2-му правилу .

после обновления

Я думаю, что ваша проблема была здесь, добавьте цель под именем "ExceptionTracking", в то время как правило сделано для "ChangeTracking". Я думаю, что это было включено при тестировании:

 //LogManager.Configuration.AddTarget("ExceptionTracking", dbTarget);

Я добавил несколько комментариев, чтобы прояснить ситуацию:

var changeTrackingDbTarget = new DatabaseTarget()
{
    Name = "ChangeTracking",
  ...
};

...

// add rule to target with name ChangeTracking
config.LoggingRules.Add(new LoggingRule("*", LogLevel.Info, changeTrackingDbTarget));

// register target not under ChangeTracking, but under ExceptionTracking
LogManager.Configuration.AddTarget("ExceptionTracking", dbTarget);
LogManager.Configuration = config;
...