I spent time trying to track down in the MQWEB server, why my JSON Web Token was not working as I expected . I found it hard to trace the problem, and tried many trace parameters till I found some which provided the information I needed. It was not an easy journey.
This blog entry covers
- How to set the trace
- The trace files did not have enough information in them
- What level of trace do you need – too much info?
- Putting your definitions in a separate file
- Displaying the trace record so it fits in the window
- How I do tracing
How to set the trace
I tried the trace
setmqweb properties -k traceSpec -v ...
described here, but this was slow and had the side effect in that it inserted blank lines to the mqwebuser.xml file, and made each xml entry one long line, and lost all of my nice formatting!
Alternatives
- I used the z/OS console command
- I edited the mqwebuser.xml file and this did all I wanted.
Using the z/OS console command
For example
f csq9web,LOGGING='*=info:zos.*=finest'
Issuing the command from the console means that the mqwebuser.xml file is not changed, and when you restart the MQWEB server it comes up with what you specified – rather than the last setmqweb command.
Editing the mqwebuser.xml manually
For MQ the trace definition is taken from the variable traceSpec.
For example
<variable
name="traceSpec"
value="*=info"
/>
I just added some more definitions
<variable
name="traceSpec"
value="*=info"
/>
<variable
name="traceSpec"
value="*=info:com.ibm.ws.webcontainer.security.ProviderAuthenticationResult=all"
/>
The last value is used – so my trace definition was used.
I could easily move these around to get different traces.
When the MQWEB server is restarted, the last definition will be used – so remember to move the normal entry to the end of the definitions (with value=”=info” or similar).
Using a more complex value
The trace entry I was given was over 150 characters long, and was difficult to enter into the file or on the command line. I had to enter it in pieces, and kept getting blanks in the wrong place. You can use symbol substitution
<variable
name="t1"
value="*=info"
/>
<variable
name="t2"
value="zos.*=all"
/>
<variable
name="traceSpec"
value="${t1}:${t2}"
/>
This produced a trace *=info:zos.=all
Whenever you change the trace, check in the message.log or trace.log file, and fix any problems.
If the update is successful, there should be an entry in the job log, such as
[AUDIT ] CWWKG0017I: The server configuration was successfully updated in 0.265 seconds.
If you do not get this, then check the log files (again).
The trace files did not have enough information in them.
Some of the traces I was given to solve my problem produced thousands of lines of output. It was hard to find the records of interest.
One record was
∇8/9/25, 16:18:52:470 GMT ∆ 00000102 Authenticatio < getStatus Exit
FAILURE
Where Authenticatio is a small part of the trace id.
I specified
<logging traceFormat="ENHANCED" />
See traceFormat and value ENHANCED.
This gave me
8/9/25, 16:22:37:516 GMT ∆ 000000f1 id=dd803e1d com.ibm.ws.webcontainer.security.AuthenticationResult < getSta…
FAILURE
You can see a more complete trace entry (com.ibm.ws.webcontainer.security.AuthenticationResult ) for the record.
You can now specify this trace entry in the <variable name=”t2″ value=”…” . And restrict which entries you want, for example value=”com.ibm.ws.webcontainer.security.*=all” .
Once I had found which trace records I wanted, I went back traceFormat=”SIMPLE” because the output was easier to read.
Useful trace entries
To get JWT information
io.openliberty.security.*=all
Why JWT faildation failed
org.apache.http.client.*=all
My definitions for these were
name="t1"
value="*=info"
/>
<variable
name="t3"
value="org.apache.http.client.*=all"
/>
<variable
name="t4"
value="io.openliberty.security.*=all"
/>
<variable
name="traceSpec"
value="${t1}:${t3}:${t4}"
/>
<logging traceFormat="SIMPLE" />
What level of trace do you need – too much info?
A trace entry with value=”io.openliberty.security.*=all” can produce a lot of output.
You may get enough to debug your problem using value=”io.openliberty.security.*=fine“, value=”io.openliberty.security.*=finer“, or value=”io.openliberty.security.*=finest“
Putting your definitions in a separate file
I put some of my definitions in a separate file trace.xml
<server>
<!-- always specify this one -->
<variable
name="t1"
value="*=info"
/>
...
</server>
You can incorporate these changes using
<include location="trace.xml"/>
<!-- and use the definitions -->
<variable
name="traceSpec2"
value="${t1}:${t2}:${t3}"
/>
If you change the trace.xml file, it will not cause MQWEB to reprocess it. You need to make a change (such as change a blank to a blank) to mqwebuser.xml for MQWEB to notice and process the file.
Displaying the trace record so it fits in the window
A trace record can be hundred of characters long – and requires to scroll sideways many pages.
The blog post Processing lines in ASCII files in ISPF edit macros has a useful ISPF edit macro which displays a row from the file, flowed so it fits into the screen width – and as the trace files are in ASCII, converts the output to displayable EBCDIC.
This made looking at the data much easier.
How I do tracing
I am the only person on my z/OS machine, which make debugging problems much easier. With all my attempts to resolve problems, I found my trace log and message log files were getting too large for me to use ISPF edit on them.
Below is how I use the trace files, it generally works.
- I edit the file, delete most of the record to leave one or two records, then save it.
- I run my test
- I edit the file again and it should have only the entries added since the first step.
Note, if you delete the file the logging code, detects the file is deleted, and stops writing to it. If you delete rows, then records are written to the end of the current file.

