Filtering App Insights Server-side Trace messages

Previously I posted about using a Log4Net Appender to record Sitecore logs to Application Insights. That code will write Trace Messages to App Insights. I’m already filtering the messages to WARN or above using standard Log4Net <filter>s – but what if I need to filter more particular messages. Well, I wrote a telemetry processor to do this, just like Requests and Dependencies.

public class TraceFilter : ITelemetryProcessor
{
	private readonly ITelemetryProcessor _nextProcessor;
	
	public string MessageRegex { get; set; }
	public string Category { get; set; }
	public string LoggerName { get; set; }
	public string UserName { get; set; }

	public string FilterIfAllMatch { get; set; }


	private Regex _rgx = null;
	private bool _rgxInited = false; 


	public TraceFilter (ITelemetryProcessor nextProcessor)
	{
		FilterIfAllMatch = "true";  //Default to all must match
		_nextProcessor = nextProcessor;
	}

	public void Process(ITelemetry telemetry)
	{
		TraceTelemetry traceTelemetry = telemetry as TraceTelemetry;
		if (traceTelemetry != null)
		{
			int rule = 0;
			int pass = 0;

			if(!string.IsNullOrEmpty(MessageRegex))
			{
				if (_rgx == null && !_rgxInited)
				{
					_rgxInited = true;
					try
					{
						_rgx = new Regex(MessageRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled);
					}
					catch (Exception ex)
					{
						Log.Warn(string.Format("Application Insights: {0} - {1}", ex.GetType().ToString(), ex.Message), this);
						_rgx = null;
					}
				}

				if (_rgx != null)
				{
					rule++;
					if (!_rgx.IsMatch(traceTelemetry.Message))
					{
						pass++;
					}
				}
			}

			if (!string.IsNullOrEmpty(Category))
			{
				rule++;
				if (!traceTelemetry.Properties["Category"].Equals(Category, System.StringComparison.OrdinalIgnoreCase))
				{
					pass++;
				}
			}

			if (!string.IsNullOrEmpty(LoggerName))
			{
				rule++;
				if (!traceTelemetry.Properties["LoggerName"].Equals(LoggerName, System.StringComparison.OrdinalIgnoreCase))
				{
					pass++;
				}
			}

			if (!string.IsNullOrEmpty(UserName))
			{
				rule++;
				if (!traceTelemetry.Properties["UserName"].Equals(UserName, System.StringComparison.OrdinalIgnoreCase))
				{
					pass++;
				}
			}

			if (FilterIfAllMatch == null || FilterIfAllMatch.Equals("true", System.StringComparison.OrdinalIgnoreCase))
			{
				// If all rules match, then there are no passes.
				if (pass == 0 && rule > 0) return;
			} else
			{
				// Else if any rules match, then there are no passes
				if (pass < rule) return;
			}
		}

		_nextProcessor.Process(telemetry);
	}

	public override string ToString()
	{
		return string.Format("TraceFilter: {0} , {1}, {2}, {3}, {4}", MessageRegex, Category, LoggerName, UserName, FilterIfAllMatch);
	}
}

It can filter by a message (by Regex) or Category (see the appender), or LoggerName (which seems to be the class that raised the log message, not the Log4Net <logger>), or UserName (which seems to be what the app pool is running as).

Filtering App Insights Server-side Trace messages

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.