Nlog: ConditionBasedFilter not being applied to target in c#

Created on 19 May 2017  路  3Comments  路  Source: NLog/NLog

Hi! Thanks for reporting this feature/bug/question!

Please keep / fill in the relevant info from this template so that we can help you as best as possible.

For .NET Core users, please check the platform support: https://github.com/NLog/NLog/wiki/platform-support

Type (choose one):

  • Bug

NLog version: Installed 4.4.9

Platform: .NET 4.6.2

Current NLog config (xml or C#, if relevant)
```c#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NLog;
using NLog.Config;
using NLog.Filters;
using NLog.Layouts;
using NLog.Targets;

namespace TestNLog
{
class Program
{

    private const string GENERAL_LOG_LAYOUT =
        @"${date:padding=-19}   ${machinename}  ${event-context:item=ActivityId} [${event-context:item=UserId:padding=7:padCharacter=0}] ${literal:text=Id\: :when='${event-context:item=Id}' != '' and ('${message}' == '' or level == LogLevel.Error)}${event-context:item=Id:when='${event-context:item=Id}' != '' and ('${message}' == '' or level == LogLevel.Error)}${literal:text=; :when='${event-context:item=Id}' != '' and ('${message}' == '' or level == LogLevel.Error)}";


    static Program()
    {
        LoggingConfiguration nLogConfig = new LoggingConfiguration();

        var targetedFileInfo =
            new FileInfo("C:\\Users\\user\\Desktop\\TargetedLog.log");

        var targetedLoggingTarget = CreateFileTarget(targetedFileInfo, "Targeted Log",
            targetedFileInfo.DirectoryName + "\\Archive\\{#}." + targetedFileInfo.Name);
        var targetedLoggingConditonFilter = SetupNlogIdCustomFilter(Filter);



        LoggingRule moduleRule = new LoggingRule("*",
            LogLevel.Debug, targetedLoggingTarget);
        moduleRule.Filters.Add(targetedLoggingConditonFilter);


        nLogConfig.LoggingRules.Add(moduleRule);

        nLogConfig.AddTarget("Targeted Log", targetedLoggingTarget);
        LogManager.Configuration = nLogConfig;
        //LogManager.ReconfigExistingLoggers();  IS THIS NEEDED?
    }

    private static Filter SetupNlogIdCustomFilter(string concatenatedIds)
    {
        ConditionBasedFilter filter = new ConditionBasedFilter();
        filter.Condition = CreateIdCondition(concatenatedIds);
        filter.Action = FilterResult.Log;
        return filter;
    }


    private static string CreateIdCondition(string concatenatedIds)
    {
        string[] ids = concatenatedIds.Split(',');
        string response = string.Empty;
        for (int idCount = 0; idCount < ids.Length; idCount++)
        {
            if (idCount > 0)
            {
                response = string.Concat(response, " || ");
            }

            var insertedIdsInIdPlaceholder = "equals('${event-properties:item=Id}','577')";
           //  this works when setting this and setting the log to Ignore - var insertedIdsInIdPlaceholder = "equals('4009','4009')"; 

            response = string.Concat(response, insertedIdsInIdPlaceholder);
        }

        return response;
    }


    private static FileTarget CreateFileTarget(FileInfo fileInfo,
        string fileTargetName, string archiveFileName)
    {
        FileTarget fileTarget = new FileTarget();
        fileTarget.Name = fileTargetName;
        fileTarget.ArchiveFileName = archiveFileName;
        fileTarget.Layout = new SimpleLayout(GENERAL_LOG_LAYOUT);
        fileTarget.ArchiveAboveSize = 1234 * 1024;
        fileTarget.ArchiveNumbering = ArchiveNumberingMode.Rolling;
        fileTarget.AutoFlush = true;
        fileTarget.CreateDirs = true;
        fileTarget.DeleteOldFileOnStartup = false;
        fileTarget.EnableFileDelete = true;
        fileTarget.FileName = fileInfo.FullName;
        fileTarget.MaxArchiveFiles = 2;
        fileTarget.ReplaceFileContentsOnEachWrite = false;
        return fileTarget;
    }


    static void Main(string[] args)
    {
        LogEventInfo logEntry = new LogEventInfo
        {
            LoggerName = "test",
            Message = string.Empty,
            TimeStamp = DateTime.UtcNow,
        };

        logEntry.Properties["ActivityId"] = Guid.NewGuid().ToString();
        logEntry.Properties["EventID"] = "3456";
        logEntry.Properties["Id"] = "400";

        Log(logEntry);
    }

    private const string Filter = "577";

    /// <summary>
    /// Writes a message to the log.
    /// </summary>
    public static void Log(LogEventInfo logEvent)
    {
        var logger = LogManager.GetLogger("Test", typeof(NLog.Logger));

        logEvent.Level = LogLevel.Debug;
        logger.Log(logEvent);
    }
}

}

```

In the example above, it should only log when the Id is equal to 577 as I have hardcoded it. It will log anything passed in regardless.

Am I setting my condition up correctly? Also, am I retrieving the Id out of the event-properties right? I assume it will be a string when doing the comparison.

  • What is the expected result?
    Filter containing a ConditionBasedFilter should only log statements that meet the conition.

  • Did you checked the Internal log?
    yes Similar (https://github.com/NLog/NLog/issues/1542)

  • Please post full exception details (message, stacktrace, inner exceptions)
    no exception being throw. Condition is just not being applied.

  • Are there any work arrounds? yes/no
    no

  • Is there a version in which it did worked?
    Not that I am aware of.

nlog-configuration question

All 3 comments

/LogManager.ReconfigExistingLoggers(); IS THIS NEEDED?

no as this only needed if you change your config after you have written some logs

PS: now checking your code

AFAIK adding a filter with action=log, doesn't mean all others are ignored.

You need to:

  1. inverse the condition and action=ignore
  2. OR, add a 2nd filter that ignores all

have to agree it's a bit strange.

I assume your question has been answered, if not, let us know!

Was this page helpful?
0 / 5 - 0 ratings