If the built-in filters do not meet your requirements, you can extend the OpenEdge Logger framework by writing your own custom filter.

Overview of steps to create a custom filter

Follow these steps to create a custom filter:
  1. Create an ABL class that implements the ILoggerFilter interface.
  2. Register the filter using the LoggerFilterRegistry.
Note: If the custom filter requires additional properties to be set in the logging.config file, you need to perform additional steps. See Create a custom filter with additional properties.

Implement the ILoggerFilter interface

Create an ABL class that implements the OpenEdge.Logging.Filter.ILoggerFilter interface. This interface provides a method named ExecuteFilter() that takes a LogEvent object as an input parameter.
Override this method and write your custom filter code inside it. Typically, you will want to manipulate the LogEvent object's properties. In the following example, the custom filter code retrieves the log message from the LogEvent object's Message property and reverses the order of the words in the message:
using OpenEdge.Logging.Filter.ILoggerFilter.
using OpenEdge.Logging.LogEvent.
using OpenEdge.Core.StringConstant.

class Filters.ReverseWordsFormat implements ILoggerFilter: 
    
    method public void ExecuteFilter(input poEvent as LogEvent):

        define variable loop as integer no-undo.
        define variable cnt as integer no-undo.
        define variable newMessage as character no-undo.
        
	   //Get the number of words in the log message
        assign cnt = num-entries(poEvent:Message:Message, StringConstant:SPACE).

	   //Reverse the order of the words and create a new message string
        do loop = cnt to 1 by -1:
            assign newMessage = newMessage
                              + entry(loop, poEvent:Message:Message, StringConstant:SPACE)
                              + StringConstant:SPACE.
        end.
        
	   //Copy the reversed message string to the LogEvent's message property
        assign poEvent:Message:Message = newMessage.
    end method.

end class.
To learn more about properties of the LogEvent object, see Log events.

Register the custom filter

After writing the custom filter class, you need to register it by associating a filter name with the filter class. You can then use the filter name in the "filters": [...] array in the logging.config file, just like you do with any other filter.
There are two ways to register a filter:
  • In the logging.config file (recommended)
  • In an ABL procedure

Register the custom filter in the logging.config file (recommended)

To register a custom filter in the logging.config file, add a filter object after the logger object as shown in this example:
{
   "logger": {
      "Company.Order.Sales": {
         "logLevel": INFO,
         "filters": [
                    ...
         ]
      }      
   },
  "filter": {
    "reversed_words_filter": "Filters.ReverseWordsFormat"
  }
}

Register the custom filter in an ABL procedure

To register a custom filter in an ABL procedure, use the OpenEdge.Logging.LoggerFilterRegistry class as shown in this example:
LoggerFilterRegistry:Registry:Put("reversed_words_filter", get-class(Filters.ReverseWordsFormat)).
You should do this early in your application code. For example, if your application is to be deployed to a PAS for OpenEdge instance, the code that registers your filter should be put in a session startup procedure.

Example: Using the custom filter

Building on the previous examples, here is how you would use the custom filter using the filter name (reversed_words_filter in our example) in a logging.config file:
{
   "logger": {
      "Company.Order.Sales": {
         "logLevel": INFO,
         "filters": [
             "reversed_words_filter",
		   {
                "name": "NAMED_FILE_WRITER",
                "fileName": "${msg.logger}-${today}.log"
                "appendTo": true
             }
         ]
      }
   },
   "filter": {
      "reversed_words_filter": "Filters.ReverseWordsFormat"
   }
}
For a log message produced from a statement like logger:Info("Customer found."), the formatted log output would be "found. Customer".