Use log4j2 in webmethods

Hi @StA_A_phane_Desmarais,
Thanks so much for sharing your experience with detailed workaround steps. I created an internal ticket for the respective team (MWS) and we hope to address this issue soon. If you like, you could create a ticket with support and request your ticket to be linked with this thread and that ticket (MWS-30139).

Thanks again.

Thanks for your response. I will follow the thread you have mentioned.

1 Like

Hi @Thiagarajan_Muthulingam2,
In the previous approaches, I wasn’t using any initialization service. The initialization was done by the log configuration defined by the system property -Dlog4j.configurationFile. But you could follow Jahn’s GitHub - SoftwareAG/webmethods-integrationserver-log4jdemo: Demo for custom logging with Log4J v2 in Integration Server (incl. v10.5+) for a package level Log4j2 configuration/initialization.

Hello @StA_A_phane_Desmarais,
The MWS team looked into this and shared that the issue you found is fixed in MWS_10.7_Fix2, which got released about 3 weeks ago. When reviewing the readme of this fix, please look for these defect references: MWS-29054, MWS-29016 and MWS-29532. When you get a chance, please try to apply this fix and see if the issue gets resolved without your workaround in place. If it is still an issue, please contact Software AG Global Support and mention that you like to reopen the defect # MWS-30139.

Thank you Senthil,

I was able to get my hands on the readme file for MWS_10.7_Fix2 and the description for MWS-29532 does fit my issue.

I will talk to the person in charge of applying patches on these development hosts.

1 Like

Very nice to hear Stéphane! Thanks for updating us.

Thank you for the information.

Hi Senthil,

Thank you very much for the inputs. In case of Jahn’s sample he has used log4j2.xml, our previous versions of IS were using log4j.properties. I had modified Jahn’s service for loading log4j2.properties and was able to create the log files. However was not able to write message, to do so, i had to modify the custom_wrapper config file as you suggested.

In addition, i have also added monitorInterval property for my subsequent loggerkeys to work without any manual intervention.

Thanks!

1 Like

Thanks @Thiagarajan_Muthulingam2. Very kind of you to share your experiences and solution. Much appreciated.

Sometime back while working with a consultant, I also noticed that when .properties type config file used, the configuration API calls doesn’t work but same configuration and API works if we use .xml type config file. That was strange but we all didn’t have much time to dig deeper and the consultant was ok to leave it as .xml so we left it. @Christoph_Jahn or anyone else, if you had a chance to try with properties type config file with Jahn’s package solution, please share any additional information you have.

I decided to try Christoph Jahn’s solution, using calls to some non-public Log4j2 services, adapting for my own use, and it is working. So I have 3 solutions now

  1. Using calls to non-public Log4j2 library
  2. Adding my customer log4j configuration in file logging_config.xml inside the JAR file common/lib/wm-caf-common.jar
  3. applying the patches to MWS recommended by Senthil Kumar and add my .properties file in the custom_wrapper.conf in -Dlog4j.configurationFile

Thanks to everyone who contributed to this trail. It was really helpful.

2 Likes

Critical Log4j2 vulnerability identified -

News Article - Critical Apache Log4j 2 bug under attack; mitigate now | TechTarget

Remediation for SwAG Products - Log4j Zero-Day security vulnerability for webMethods - Service project (softwareag.com)

KM

3 Likes

Hi Senthil,

If we use Integration Server and MWS 10.11 instead of 10.7, is this fix is already included in 10.11 ?

Hi Stéphane,

I don´t think so.

wM 10.11 was released in October 2021 and the log4j issue came up in Mid of December 2021.
There were some fixes released in the last few days so you should check your UpdateManager for recent fixes.
Check Empower for the Remediation Advisory for this issue additionally.

Regards,
Holger

Hi Holger,

My question is not about the log4j2 vulnerability. It’s for my original question regarding the fact that our changes to log4j2.properties file were being ignored midway through starting Integration Server, and for which Senthil said to see fix in 10.7:

MWS-29532 (MWS_10.7_Fix2)
When initializing, the Common Directory Services package in Integration Server changes the value
of the log4j.configurationFile system property and redirects the log output for ActiveTransfer.log
to the wrapper.log
(reference: https://empower.softwareag.com/sl24sec/fixsis_extern/FIXSIS2/ALL/MWS/107/MWS_10.7_Fix2_Readme.txt?prdfamily=webMethods

@StA_A_phane_Desmarais , changes are part of 10.11 GA release for MWS-29532.

Regards,
-Kalpesh

Side note: this entire thread reinforces that we made the right decision to avoid direct use of log4j like the plague. As with so many libraries/facilities that originally started off lean and useful, this one has gone bonkers and tries to do far too much, IMO (and we get mind-boggling vulnerability because of a freaking logging utility!?). Of course YMMV.

For custom logging we created a couple of helper services. First is a wrapper service that uses the same class IS uses internally to write and daily rotate stats.log.

// Wrapper service for com.wm.app.b2b.server.ServerAPI.getLogStream.
// This is what IS uses internally to write and rotate stats.log.
//
// Opens a log file in the server's default logs directory. 
// This should only be used to obtain handles to new log files for 
// solution-specific logging purposes. By convention, the name should 
// be something like "myapp.log".
// 
// The returned stream is intended to kept open for the life of the
// JVM (don't open a whole bunch of these).
// 
// This service maintains a hash table of log streams that have
// been opened keyed by the logfile parameter. If the log has 
// been previously opened, the existing stream is returned and 
// the "newLog" is set to "false". If the log is opened for the
// first time a new stream is returned and the output parameter
// "newLog" is set to "true".
public static final void getLogStream(IData pipeline) throws ServiceException {
	IDataCursor idc = pipeline.getCursor();
	String logfile = IDataUtil.getString(idc, "logfile");

	boolean newLog = false;
	com.wm.app.b2b.server.LogOutputStream os = 
	  (com.wm.app.b2b.server.LogOutputStream)openLogFiles.get(logfile);
	
	if(os == null)
	{
		os = com.wm.app.b2b.server.ServerAPI.getLogStream(logfile);
		openLogFiles.put(logfile, os);
		newLog = true;
	}
		
	IDataUtil.put(idc, "logStream", os);
	IDataUtil.put(idc, "newLog", ""+newLog);
	idc.destroy();
}

// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> ---

private static final java.util.Hashtable openLogFiles = new java.util.Hashtable();

Next is a helper to write to the log stream. This can be adjusted to support different input types such as a byte array, but typically supporting string is sufficient.

public static final void writeLogStream(IData pipeline) throws ServiceException {
    IDataCursor idc = pipeline.getCursor();
    com.wm.app.b2b.server.LogOutputStream os = 
      (com.wm.app.b2b.server.LogOutputStream)IDataUtil.get(idc, "logStream");
    String message = IDataUtil.getString(idc, "message");
    idc.destroy();
    
    os.write(message);
}

A FLOW service would call getLogStream to create/get a stream and then write to it using writeLogStream.

For a given log, one can create another service that encapsulates the filename and the writing in a single call:

writeMyLog
..Input: message (string)
..Output: (none)
..Tree:
....MyUtils:getLogStream
......logFile = "MyLog.log"
....MyUtils:writeLogStream
......logStream = (stream returned by getLogStream)
......message = (message passed by caller to this service)

One can create multiple “writeMyLog” services in various packages as desired. This doesn’t have all the flexibility of log4j (logging levels and all that) but doesn’t have the complexity either. :slight_smile:

Edit: Forgot to emphasize that IS will automatically rotate such logs daily, same as is done with the stats.log file.

Rob,
What mode do these log services use? Sync or Async? The only thing I like about log4j is its configurable properties at interface level and then async option. I agree with your comment on it trying to do too much.

The services themselves do not control sync/async. A caller could do something to invoke them in an async way. The javadoc for the underlying class that is used does not indicate if it is sync/async. My bet is sync.

Beware the desire to use async under the impression that it will be faster. There is a very high probability that the time taken to write a log sync does not matter at all for a given integration. Doing async logging by default may fall under the “don’t optimize prematurely” guideline. :slight_smile:

One could add a simple mechanism to control what gets logged and what doesn’t in the write service, but we’ve found (so far) that the broad brush approach is sufficient. Just write to the log and have a scheduled task to remove old logs each week/month/whatever. Keeps things simple.

Hi,
This is extension to my original question. now i could write to custom log file using webMethods 10.5 and log4j2 by following @Christoph_Jahn 's solution.
Now, I have a dependent jar file to that package and that also need to write log to the same custom log file. As logger instance will be created only once i expect the logger statements inside the jar to write to same custom log file as webMethods code does. But, It’s not working. Kindly help me here if you have any idea.
Thanks in Advance!
Vignesh

Hi @Senthil

I am going through the above thread since i am implementing the custom logging framework.
I am using the SAG 10.3 version, and this is my esb.log4j2 file.

<?xml version="1.0" encoding="UTF-8"?> packages/CustomLogging/resources/logs/rolling-file.log packages/CustomLogging/resources/logs/rolling-file-%d{yyyy-MM-dd}-%i.log %d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %m%n
<Appenders>
    <RollingFile name="MyRollingFile" fileName="${FileName}" filePattern="${FileNamePattern}">
        <PatternLayout pattern="${LogPattern}"/>
        <Policies>
            <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
        </Policies>
    </RollingFile>
</Appenders>
<Loggers>
    <Logger name="COELogger" level="info" additivity="false">
	<AppenderRef ref="MyRollingFile"/>
</Logger>
</Loggers>

Now in the custom_wrapper.config can i add the properties like this

Existing one — wrapper.java.additional.204=-Dlog4j.configuration=file:///C:\SoftwareAG\IntegrationServer\instances\default\log4j.properties
Append this new one in the file – “wrapper.java.additional.206=-Dlog4j.configurationFile=C:\SoftwareAG\IntegrationServer\instances\default\packages\Pepco_Common_ErrorHandling\config\esb.log4j2.xml”.

should i add this as well “wrapper.java.additional.204.stripquotes=TRUE”

Also esb.log4j2.xml file supports in 10.3 version since there we have log4j.properties is the existing one?
Can someone please help me how to implement it?