Wednesday, October 29, 2025

Deleting the journal receivers of QAUDJRN

QAUJRN is the system's audit journal that captures various pieces of information that you want it to. A friend has a job that uses the Display Journal command, DSPJRN, to retrieve the data from QAUDJRN.

01  DSPJRN JRN(QSYS/QAUDJRN) RCVRNG(*CURCHAIN) +
02               FROMTIME(&FROMTIME) TOTIME(&TOTIME) +         
03               ENTTYP(AF) +
04               OUTPUT(*OUTFILE) OUTFILE(SOMELIB/JRN_AF)

One day his job errored, and he reached out to me for help as it returned an error he had never seen before. He sent me the job log, and I found the following within it:

CPF7053    Escape     40   MM/DD/YY  11:30:00.444197  QJODSPJE     QSYS        0698     QSECAUDR    
Message . . . . :   Values for RCVRNG parameter not correct; reason code 4.

4 - There are more than the maximum number of allowed receivers in the receiver chain for the 
operation being performed. The maximum supported number is 2045.

Checking IBM's documentation for the DSPJRN command's RCVRNG parameter it explains:

Range of journal receivers (RCVRNG)

Note: If the maximum number of receivers (2045) in the range is surpassed, an error occurs, 
and no journal entries are converted.

How do we find how many QAUDJRN journal receivers there are?

I went to the SQL View JOURNAL_INFO with the following statement:

01  SELECT JOURNAL_NAME AS "Journal",
02         ATTACHED_JOURNAL_RECEIVER_LIBRARY AS "Rcvr lib",
03         NUMBER_JOURNAL_RECEIVERS AS "No. rcvrs"    
04    FROM QSYS2.JOURNAL_INFO
05   WHERE JOURNAL_NAME = 'QAUDJRN'

Lines 1 – 3: I have given the columns shorter column headings as their names, especially the second one, are very long.

Line 5: I have not bothered to give a library as there can only be one QAUDJRN, and it is found in the library QSYS.

The results were:

Journal   Rcvr lib    No. rcvrs
-------   ---------   ---------
QAUDJRN   QGPL             2085

There are more journal receivers, 2085, than the command's maximum allowed value, 2045.

How do I get a list of those journal receivers? I used the JOURNAL_RECEIVER_INFO View:

01  SELECT JOURNAL_NAME AS "Journal",
02         JOURNAL_RECEIVER_LIBRARY AS "Rcvr lib",
03         JOURNAL_RECEIVER_NAME AS "Rcvr name",
04         DATE(ATTACH_TIMESTAMP) AS "Attached",
05         DATE(DETACH_TIMESTAMP) AS "Detached",
06         STATUS 
07    FROM QSYS2.JOURNAL_RECEIVER_INFO       
08   WHERE JOURNAL_NAME = 'QAUDJRN'
09   ORDER BY "Attached"

Lines 1 – 5: I have given the columns new column heading to make them easier to show below.

Lines 4 and 5: I only need to know the date from these timestamps, therefore, I have used the DATE scalar function to convert the timestamp values to dates.

Line 6: This is whether the receiver is attached, online (unsaved), or saved.

Line 9: Notice how I use the column heading in the Order by clause.

I am not going to show all of the results, just the first and last few:

Journal   Rcvr lib   Rcvr name    Attached     Detached    Status
-------   --------   ----------   ----------   ----------  --------
QAUDJRN   QGPL       AUDRCV0001   2022-04-15   2022-04-15  SAVED
QAUDJRN   QGPL       AUDRCV0002   2022-04-15   2022-05-17  SAVED
QAUDJRN   QGPL       AUDRCV0003   2022-04-17   2022-05-18  SAVED

QAUDJRN   QGPL       AUDRCV2083   2025-11-05   2025-11-08  ONLINE
QAUDJRN   QGPL       AUDRCV2084   2025-11-08   2025-11-12  ONLINE
QAUDJRN   QGPL       AUDRCV2085   2025-11-12   <NULL>      ATTACHED

Now I have identified all the QAUDJRN journal receivers, I consulted my friend to establish the rules for deleting the journal receivers.

  • They have been saved
  • They are older than 18 months

Fortunately those are parameters in the DELETE_OLD_JOURNAL_RECEIVERS procedure:

01  CALL SYSTOOLS.DELETE_OLD_JOURNAL_RECEIVERS(
02          DELETE_OLDER_THAN => CURRENT_DATE - 18 MONTHS,
03          JOURNAL_RECEIVER_LIBRARY => 'QGPL',
04          JOURNAL_RECEIVER => 'AUDRCV%',
05          PREVIEW => 'YES')

Line 2: This is where I say that I only want to delete journal receivers that are older than 18 months.

Line 3: All of the QAUDJRN journal receivers are in the library QGPL.

Line 4: All of their names start with "AUDRCV", the percent sign ( % ) acts as the wildcard symbol.

Line 5: I strongly recommend that you start in Preview mode to make sure you have selected the journal receivers you want to delete. If you do not use Preview mode you might accidentally delete journal receivers before you are ready to do so.

I am not going to show the results of this statement as the results are the same as those from JOURNAL_RECEIVER_INFO.

I am not going to want anyone to execute the DELETE_OLD_JOURNAL_RECEIVERS procedure, where Preview = no, more than once. It makes sense to have a program that does this, that can be added to the job scheduler. I decided to write an RPG program that looks like:

01  **free
02  ctl-opt main(Main) option(*srcstmt) ;

03  dcl-proc Main ;
04    exec sql CALL SYSTOOLS.DELETE_OLD_JOURNAL_RECEIVERS(
05                     DELETE_OLDER_THAN => CURRENT_DATE - 18 MONTHS,
06                     JOURNAL_RECEIVER_LIBRARY => 'QGPL',
07                     JOURNAL_RECEIVER => 'AUDRCV%',
08                     PREVIEW => 'NO') ;
09    return ;
10  end-proc ;

Line 1: I have not said for some time in my posts, if you are writing RPG in 2025 you need to be using totally free RPG.

Line 2: Another thing you should be doing in modern RPG is not using the RPG cycle. The way to "turn off" the RPG cycle is to have a main procedure. And that is followed by my favorite control option.

Line 3: Start of the Main procedure.

Line 5: Delete journal receivers that are more than 18 months old.

Line 6: All of the journal receivers for the QAUDJRN journal receivers are in the library QGPL.

Line 7: All of journal receiver's names start with "AUDRCV".

Line 8: Preview is "NO", therefore, the journal receivers that conform to the selection criteria are deleted.

After the program was compiled I called it. When preview is no a file is created in QTEMP called QDLTJRNRCV. Every time the procedure tries to delete a journal receiver a row is inserted into the file documenting whether the deletion was successful or not.

When the program finished I used the following statement to see the results of the deletions.

01  SELECT DELETE_JOURNAL_RECEIVER_RESULT,
02         JOURNAL_RECEIVER_LIBRARY,
03         JOURNAL_RECEIVER_NAME
04    FROM QTEMP.QDLTJRNRCV

Line 1: To check the success of the deletions I can look at DELETE_JOURNAL_RECEIVER_RESULT.

Lines 2 and 3: The journal receivers' library and name.

I am only showing the first few results:

DELETE_
JOURNAL_    JOURNAL_    JOURNAL_
RECEIVER_   RECEIVER_   RECEIVER_
RESULT      LIBRARY     NAME
---------   ---------   ----------
SUCCESS     QGPL        AUDRCV0001
SUCCESS     QGPL        AUDRCV0002
SUCCESS     QGPL        AUDRCV0003

When this program was run on my friend's partition more than one thousand journal receivers were deleted, and the storage utilization decreased by 13%. This is a good example of why deleting old and unwanted things is a good task to perform regularly.

I need to mention this too. I no longer use the DSPJRN command to get data from journals. I use the SQL DISPLAY_JOURNAL table function as I think it is easier to use and is more flexible than DSPJRN.

For many of the QAUDJRN entry types there are specific SQL table functions, AUDIT_JOURNAL_XX (there are now more table functions than those listed in the linked post), that allow me to extract just that entry type's data. For example:

01  SELECT * 
02  FROM TABLE(SYSTOOLS.AUDIT_JOURNAL_AF(
03               STARTING_TIMESTAMP => CURRENT TIMESTAMP - 7 DAYS))

My preference would be be to use the Audit Data Mart, to extract and retain this data.

01  CALL QSYS2.MANAGE_AUDIT_JOURNAL_DATA_MART(
02           JOURNAL_ENTRY_TYPE => 'AF',
03           DATA_MART_LIBRARY => 'SOMELIB',
04           STARTING_TIMESTAMP => '*CONTINUE',
05           DATA_MART_ACTION => 'ADD')

Even using my DSPJRN alternatives does not remove the need to delete old QAUDJRN journal receivers.

 

This article was written for IBM i 7.6, and should work for some earlier releases too.

No comments:

Post a Comment

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.