The OpenEdge Logger Framework allows you to customize the format of the client log file. It was implemented for code that runs on PAS for OpenEdge and is also used in a normal ABL client. For example, in the prowin.exe file.

Follow these steps to generate the desired log format:
  1. Create a logging.config file in the PROPATHdirectory and add the following content:
    {
     "logger": {
       "MyLogger1": {
         "logLevel": "TRACE",
         "filters": [
           "custom_filter",
           {
            "name": "NAMED_FILE_WRITER",
            "fileName": "client.log",
            "appendTo": true
           }
         ]
       }
     },
     "filter": {
       "custom_filter": "Filters.CustomFormat"
     }
    }
  2. Create a directory called Filters and create a class named CustomFormat.cls in it. Ensure this directory is placed in a location that is part of the PROPATH. Add the following code in the class:
    USING OpenEdge.Logging.Filter.ILoggerFilter.
    USING OpenEdge.Logging.LogEvent.
    USING OpenEdge.Core.StringConstant.
    
    CLASS Filters.CustomFormat IMPLEMENTS ILoggerFilter: 
        
        METHOD PUBLIC VOID ExecuteFilter(INPUT poEvent AS LogEvent):
            
            DEFINE VARIABLE pName AS CHARACTER NO-UNDO.
            DEFINE VARIABLE pID AS INTEGER NO-UNDO.
    
            IF OPSYS = "UNIX" THEN DO:
                pName = SUBSTRING(PROGRAM-NAME(4), R-INDEX(PROGRAM-NAME(4), "/") + 1). 
                RUN getpid(OUTPUT pID).
            END.
            ELSE
                IF OPSYS = "WIN32" THEN DO:
                    pName = SUBSTRING(PROGRAM-NAME(4), R-INDEX(PROGRAM-NAME(4), "\") + 1). 
                    RUN GetCurrentProcessId(OUTPUT pID).
                END.
                ELSE
                    ASSIGN pID = ?.
    
            //Define format
            ASSIGN 
                poEvent:Message:Message = SUBSTITUTE('&1 [&2-&3] &4 &5':U,
                                                /*1*/ STRING(poEvent:TimeStamp,"99-99-99 HH:MM:SS"),
                                                /*2*/ pName,
                                                /*3*/ pID,
                                                /*4*/ STRING(poEvent:LogLevel),
                                                /*5*/ poEvent:Message:Message).
                                                
        END METHOD.
        
        PROCEDURE getpid EXTERNAL "/usr/lib/libc.1":U CDECL:
            DEFINE RETURN PARAMETER ppid AS LONG NO-UNDO.
        END PROCEDURE.
        
        PROCEDURE GetCurrentProcessId EXTERNAL "kernel32.dll":U:
            DEFINE RETURN PARAMETER ppid AS LONG NO-UNDO.
        END PROCEDURE.
    
    END CLASS.
  3. Run the following code to create a client.log file:
    USING OpenEdge.Logging.*.
    
    DEFINE VARIABLE Logger AS ILogWriter NO-UNDO.
    Logger = LoggerBuilder:GetLogger('MyLogger1').
    Logger:Info('Log started').
    Logger:Trace('Writing to log').
    Logger:Info('Log ended').