Adding custom token handlers to the LAB TextFormatter is fairly simple. The following formatter adds an "arrow" token (" --> ") to  the formatter.

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;

namespace MyLibrary.Logging.EnterpriseLibrary
{
    [ConfigurationElementType(typeof(CustomFormatterData))]
    public class CustomTextFormatter : TextFormatter
    {
        #region Private Fields

            private static readonly Dictionary<string, TokenHandler<LogEntry>> tokenHandlers =
                new Dictionary<string, LogEntry>>();

        #endregion

        #region Constructors

            static CustomTextFormatter()
            {
                tokenHandlers["arrow"] = GenericTextFormatter<LogEntry>
                    .CreateSimpleTokenHandler(" --> ");
            }

            public CustomTextFormatter(NameValueCollection parameters)
                : this(parameters.Get("template")) { }

            public CustomTextFormatter() : this(null, tokenHandlers) { }

            public CustomTextFormatter(string template) : this(template, tokenHandlers) { }

            protected CustomTextFormatter(string template, Dictionary<string, TokenHandler<LogEntry>>
                extraTokenHandlers) : base(template, extraTokenHandlers) { }

        #endregion    
    }
}

A few things to note: 1) If you want to define the formatter in configuration, you must add the CustomFormatterData attribute to the class. Don't try to add the the TextFormatterData attribute as I did (Because I did not pay close enough attention to the documentation!) and spend hours in Reflector trying to figure out why a TextFormatter object is created and not the derived type... This, by the way, has to do with the Assembler attribute on the nnnFormatterData class. This attribute references an assembler class that will instantiate the specific type (In this case the XmlLogFormatter), NOT the one specified in configuration. You could also define your own custom FormatterData and Assembler classes but the using the CustomFormatterData class is much simpler. 2) Again, if you want to define the formatter in configuration, you will need to add the constructor that accepts the NameValueCollection of configuration parameters. You can then grab the template parameter from this collection. 3) Create a static list of handlers that gets initialized once by a static constructor. There is no need to keep recreating these objects every time the formatter is created.

To define the formatter in configuration, specify the class reference like you normally would, just point to the new class. You can now use the token you defined in your class.

<formatters>
  <add 
    name="EventLogFormatter" 
    template="Timestamp{arrow}{timestamp}
Message{arrow}{message}
 ..."
    type="MyLibrary.Logging.EnterpriseLibrary.CustomTextFormatter, MyLibrary"
     />
formatters>

The result is as follows:

image

Now obviously you'll want to do more than add a simple token. In our next installment we will show you how to add a parameterized token. See you next time.