How to create a custom logging severity filter?

Topics: Building and extending application blocks, Logging Application Block
Feb 2, 2010 at 5:05 AM

Below is my code for the custom filter class

[ConfigurationElementType(typeof(CustomLogFilterData))]
public class SeverityFilter : LogFilter
{
	private NameValueCollection _attributes;

	public SeverityFilter(string name) : base(name) { }

	public SeverityFilter(NameValueCollection attributes) : base("Severity Filter")
	{
		_attributes = attributes;
	}

	public override bool Filter(LogEntry log)
	{
		// Loop through all the categories and if a match is found
		// determine if the message should be logged
		for (int i = 0; i < log.CategoriesStrings.Length; i++)
		{
			string severity = _attributes.Get(log.CategoriesStrings[i]);
			if (!String.IsNullOrEmpty(severity))
			{
				TraceEventType allowedSeverity = (TraceEventType)Enum.Parse(typeof(TraceEventType), severity);
				return ShouldLog(allowedSeverity, log.Severity);
			}
		}

		return true;
	}

	public bool ShouldLog(TraceEventType severity, TraceEventType allowedSeverity)
	{
		// The TraceEventType have integer representations
		// that gets higher the lower criticality.
		// e.g 
		// Critical = 1, Verbose = 16
		if (Convert.ToInt32(allowedSeverity) >= Convert.ToInt32(severity))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}
What I want to achieve is that I have some assemblies, each of which will log to different files. Further, I also want an option for logging level so that when one of the assembly logs it first check its log level and see if the level of this log is allowed etc. How do I accomplish this? Am I going in the right direction?

Feb 2, 2010 at 5:42 AM

Hmm, I don't see the relevance of creating a custom filter.  The logic that I can see in your class is already being performed by LAB.  If you set the Filter property of a trace listener, only those type of logs which are greater than or equal to the value of the Filter property will be logged.  As for separating files for each assembly, you can do this by adding different trace listener to different categories and use each one of them to a single assembly.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Feb 2, 2010 at 5:51 AM
AvanadeSupport wrote:

Hmm, I don't see the relevance of creating a custom filter.  The logic that I can see in your class is already being performed by LAB.  If you set the Filter property of a trace listener, only those type of logs which are greater than or equal to the value of the Filter property will be logged.  As for separating files for each assembly, you can do this by adding different trace listener to different categories and use each one of them to a single assembly.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Can you provide an example? I'm confused by the SourceLevels property in Category Sources and Filter property in Trace Listeners?

Do you mean that I create a different category source and trace listener for each assembly I want to log in and then reference that trace listener in the category source and do the same for each?

 

Feb 2, 2010 at 6:37 AM

They're the same, the only difference is in their scope.  The SourceLevels property in the Category applies to all trace listeners belonging to it.  The Filter property in a trace listener obviously only applies to itself.  Filtering is done first on the Category level the on the trace listener.  If the Category is more restrictive, then it does not proceed to call the trace listeners.  If it allows all types of event, it then pass the log entry to each trace listener and each of them detects if it will log that entry based on its Filter.

On the second item, yes.  I don't see how are you going to that with a custom filter but if you do, enlighten me :)

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

Feb 2, 2010 at 6:45 AM

I thought there ain't such thing as a severity filter in LAB, so went on implementing my own. But since its already implemented I'll use that.

Thank you very much Avanade. That helped a lot.

Btw, if you could tell my why am I getting the "There were no types found in the assembly 'xyz' that implement or inherit from the base type 'Microsoft.Practices.EnterpriseLibrary.Logging.Filters.LogFilter'." so that in future if the need arises for a custom filter I don't get stuck again.

 

Feb 2, 2010 at 7:00 AM

You just probably need to close the visual studio IDE and try again in order to load a newer version of the assembly

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Oct 28, 2010 at 1:28 AM

Just want to correct my previous answer.  My understanding back then was that you were not aware that the Logging Application Block as a whole doesn't have the capability to filter log entries based on severity.  Sorry, stupid mistake on my part, I should've realized you were actually talking about a corresponding Logging Filter.   The behavior you want is actually, yes, can be achieve by creating a custom filter.  The code you posted would work fine.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com