Tracing MQ JMS apps in Spring

The MQ JMS packages have options to permit configuration of internal tracing and related logging features. While debugging a recent project, I wanted to look at traces of both the MQ library, and some of the surrounding Spring behaviour. While possible, it was not as convenient as I would have liked. So I’ve added some new options that simplify tracing MQ JMS apps in Spring.

I’ve written about the MQ Spring Boot Starter in several previous posts here. This module already works within the overall Spring Boot tracing framework. But in this article, I’m going to talk specifically about integrating those trace features with the trace options for the underlying MQ JMS client. Which are more convoluted than perhaps necessary.

The MQ JMS trace properties

The first thing to realise is that “trace” actually covers three different aspects of reporting the JMS behaviour: service-level trace, error logging, and FFDCs. The configuration options vary for each of these components. Some can be enabled or disabled entirely. The location of the output can be modified. But not all of the options are available for all components.

The error logs are comparable to a queue manager’s AMQERRxx.LOG files. These logs have a similar format and contain a similar level of information.

FFDC (or FFST or FDC) files are usually intended for more severe error reporting. They hold detailed information about the execution state of the program at the time the FFDC was issued.

With the default options, the logging is usually written to files in or under the current directory, where the program is executing. If the program cannot write to that directory, then things are usually written to stdout or stderr.

Standard Configuration

The MQ documentation describes configuration of the different logging options here and here. With some other options sprinkled around other pages. Generally, the values come directly from system properties (the -D option for Java programs) or by putting the values in configuration files that a single system property can point at. There are additional options for a JEE environment, but with Spring we only really care about the JSE pieces.

One thing I found while digging into the documentation and the properties is that some reference “FFST” options while others reference “FFDC”. Which is just one of the complications that I wanted to sort out.

While there are some references in the docs to using Java logging frameworks, the different elements do not integrate particuarly well with packages like log4j or slf4j. I found it easier to essentially ignore those packages here.

Spring Configuration

Setting system properties is of course possible when running Spring programs, but (depending on how you are building and executing) it’s not always as simple as you might like. My own test environment tends to run things out of a gradlebuild process, and setting these properties gets done by modifying the build.gradle configuration file. Which is not very convenient when you want to distribute an application.

Version 3.3.3 of the MQ Spring Boot Starter allows the properties to be set in the same way as all other Spring Boot configuration options such as the MQ channel name.

ibm:
  mq:
    queueManager: QM1
    channel: SYSTEM.DEF.SVRCONN
    connName: localhost(1414)
    trace:
      ffdcPath: /tmp/jms/FFDC
      traceFile: /tmp/jms/trace.log
      parameterTrace: true
      logFile: /tmp/jms/errors.log
      status: ON
      ffdcSuppressProbeIDs: SPRFDC1

The ibm.mq.trace block of options sets things up. For the full set of available options, see the README file in the repository. One simplification I’ve made is to permit both ffdc and ffstto be used as a prefix for the relevant values; both end up setting the right MQ value. Apart from that, the values are as described the MQ documentation. So for example, the logFile is a fixed name. While the traceFile can contain a %PID%token for runtime replacement.

Note that you cannot entirely suppress FFDCs. You can give a list of FFDCs to not report, but others will be written to the default or nominated path.

Merging MQ and Spring trace

Part of what led me to adding these options was a desire to see both the MQ and Spring trace in the same output file. The loggingstanza in the Spring configuration file controls that for the Spring Boot (including the MQ Starter) output:

logging:
  pattern:
    console:
    file: "[%date{dd/MM/yy HH:mm:ss.SSS}   ] %thread %logger{36}  %msg%n"
  file:
    name: /tmp/jms/trace.log
  level:
    root: TRACE

We disable the default console output by setting its format to be empty. While the Spring program might still try to write to the console, it’s not going to produce anything visible. The fileoutput format I’ve set here is not identical to what gets written by the MQ tracer, but it’s close enough. In particular, the Spring tracer does not show which object has caused the trace line while the MQ tracer does refer to the actual object. The Spring trace file is the same name as that in the ibm.mq.traceblock.

Extracting a few lines from the single output file, we can see information generated by both Spring and MQ JMS. The abbreviated classnames in here expand to the org.spring.... and com.ibm.mq...full names.

[28/08/24 13:51:39.537   ] main o.s.b.c.p.s.ConfigurationPropertySourcesPropertyResolver$DefaultResolver  Searching for key 'spring.jms.listener.receiveTimeout' in PropertySource 'systemProperties'
[28/08/24 13:51:39.537   ] main o.s.b.c.p.s.ConfigurationPropertySourcesPropertyResolver$DefaultResolver  Searching for key 'spring.jms.listener.receive_timeout' in PropertySource 'systemProperties'
[28/08/24 13:51:40.824.00]  00000001     static  c.i.m.j.remote.impl.RemoteTCPConnection                                ----+----+----+--  d  static SCCS id [@(#) MQMBID sn=p940-L240605.1 su=_CgQS4CM2Ee-M5d-9sa1WMw pn=com.ibm.mq.jmqi.remote/src/com/ibm/mq/jmqi/remote/impl/RemoteTCPConnection.java]
[28/08/24 13:51:40.824.07]  00000001  @2538bc06  c.i.m.j.remote.impl.RemoteTCPConnection(JmqiObject)                    ----+----+----+--  {  <init>(JmqiEnvironment) 

Summary

As always with MQ tracing, the output is primarily of interest to the IBM support teams. Though someone may find assistance in there. And I was able to verify the aspect that I was working with at the time.

But hopefully this will give an more natural way to configure it, if support do ever ask you for a trace.

This post was last updated on September 12th, 2024 at 06:45 am

Leave a Reply

Your email address will not be published. Required fields are marked *