Introduction

 
Intermittent and occasional errors present one of the greatest challenges when supporting an application or system. Until V5R4 of the iSeries, there were not many ways to intercept error messages under these conditions.
 
But as of V5R4, IBM has provided support for system-wide event watches. The watch waits until a message, LIC LOG, or (as of 6.1 of i5/OS) PAL LOG event occurs; that is, until a certain message is sent to, say, the job log of one, several, or all jobs on the system. The definition of the watch normally includes comparison data, so that the event is not triggered unnecessarily.
 

Starting a Watch (STRWCH)

The STRWCH command defines and starts a watch.
 
For example: In this case, when the message CPF4128 appears in any job log, and the message data contains the value DOCVER01, then the exit program WCHEXITC in the library VERN is called:
STRWCH SSNID(TSTWCH)
  WCHPGM(VERN/WCHEXITC)
  WCHMSG((CPF4128 DOCVER01 *MSGDTA))
  WCHMSGQ((*JOBLOG))
  WCHJOB((*ALL/*ALL))
This exit program is like any program on the iSeries - it can do whatever is allowed by the authority under which it is running. In this example, the CPF4128 message usually means that something has an exclusive lock on a file that a program is trying to open. The exit program could run the WRKOBJLCK command against the file named in the WCHMSG parameter, or even get the name from the event data that was passed into the program. The program could also print the job log of the job where the error occurred, because that job name, user, and number are included in the event data. And it could send an instructive message to the system operator.
 

Ending a Watch (ENDWCH)

 
The ENDWCH command ends a watch.
 
For example: To end the watch started in the previous example:
 
ENDWCH SSNID(TSTWCH)
 

Working with Watches (WRKWCH)

 
The WRKWCH command lets you start and end watches from a Work with... display.
 

Watch for Event Exit Program

Required Parameters

1
    Watch option setting
    Reason the exit program was called.
    Input
    Char(10)
2
    Session ID
    Name of the session that is calling the exit program.
    Input
    Char(10)
3
    Error detected
    Indicates if an error occurred in the exit program itself.
    Output
    Char(10)
4
    Event data
    Watch information, such as job in which the message event occurred, comparison and replacement data, and so on.
    Input
    Char(*)

More Information

Sample Watch Exit Program

/***********************************************************************/
/*             Author:   Vernon M. Hamberg                             */
/*       Date written:   07/11/2011                                    */
/*            Purpose:   Sample exit program for watches               */
/*                                                                     */
/*               Note:   Minimum release for this code is V5R4. The    */
/*                       variables are declared with *DEFINED and      */
/*                       *BASED storage, and pointers are used for     */
/*                       variable-length variables. Since watches were */
/*                       first introduced at V5R4, this code can be    */
/*                       used as is.                                   */
/*                                                                     */
/*            Version:   1.00                                          */
/*               Desc:   Initial sample source                         */
/***********************************************************************/
PGM        PARM(&WCHOPTSET &SESSID &ERRDTCT &EVTDTA)

/* Parameters */
DCL        VAR(&WCHOPTSET) TYPE(*CHAR) LEN(10)
DCL        VAR(&SESSID) TYPE(*CHAR) LEN(10)
DCL        VAR(&ERRDTCT) TYPE(*CHAR) LEN(10)
DCL        VAR(&EVTDTA) TYPE(*CHAR) LEN(2048) /* This should be long +
         enough to handle most situations, since the fixed portion +
         is around 450 bytes long - modify as needed */

/* Doesn't work to use *DEFINED on an incoming parameter */
DCL        VAR(&EVTDTADFND) TYPE(*CHAR) LEN(2048)

/* Event data elements - fixed-length data */
DCL        VAR(&LENWCHINF) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 1)
DCL        VAR(&MSGID) TYPE(*CHAR) STG(*DEFINED) LEN(7) +
         DEFVAR(&EVTDTADFND 5)
DCL        VAR(&RSVD1) TYPE(*CHAR) STG(*DEFINED) LEN(1) +
         DEFVAR(&EVTDTADFND 12)
DCL        VAR(&MSGQNAM) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 13)
DCL        VAR(&MSGQLIB) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 23)
DCL        VAR(&JOBNAM) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 33)
DCL        VAR(&JOBUSR) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 43)
DCL        VAR(&JOBNBR) TYPE(*CHAR) STG(*DEFINED) LEN(6) +
         DEFVAR(&EVTDTADFND 53)
DCL        VAR(&RSVD2) TYPE(*CHAR) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 59)
DCL        VAR(&SNDPGMNAM) TYPE(*CHAR) STG(*DEFINED) LEN(256) +
         DEFVAR(&EVTDTADFND 63)
DCL        VAR(&SNDMODNAM) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 319)
DCL        VAR(&OFSSNDPRC) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 329)
DCL        VAR(&LENSNDPRC) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 333)
DCL        VAR(&RCVPGMNAM) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 337)
DCL        VAR(&RCVMODNAM) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 347)
DCL        VAR(&OFSRCVPRC) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 357)
DCL        VAR(&LENRCVPRC) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 361)
DCL        VAR(&MSGSEV) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 365)
DCL        VAR(&MSGTYP) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 369)
DCL        VAR(&MSGTIMSTP) TYPE(*CHAR) STG(*DEFINED) LEN(8) +
         DEFVAR(&EVTDTADFND 379)
DCL        VAR(&MSGKEY) TYPE(*CHAR) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 387)
DCL        VAR(&MSGFNAM) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 391)
DCL        VAR(&MSGFLIB) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 401)
DCL        VAR(&RSVD3) TYPE(*CHAR) STG(*DEFINED) LEN(2) +
         DEFVAR(&EVTDTADFND 411)
DCL        VAR(&OFSCMPDTA) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 413)
DCL        VAR(&LENCMPDTA) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 417)
DCL        VAR(&CMPAGAINST) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 421)
DCL        VAR(&RSVD4) TYPE(*CHAR) STG(*DEFINED) LEN(2) +
         DEFVAR(&EVTDTADFND 431)
DCL        VAR(&CMPDTACSID) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 433)
DCL        VAR(&OFSCDTAFND) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 437)
DCL        VAR(&OFSRPLDTA) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 441)
DCL        VAR(&LENRPLDTA) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 445)
DCL        VAR(&RPLDTACSID) TYPE(*INT) STG(*DEFINED) LEN(4) +
         DEFVAR(&EVTDTADFND 449)
DCL        VAR(&SNDUSRPRF) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 453) /* 6.1 */
DCL        VAR(&TGTJOBNAM) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 463) /* 6.1 */
DCL        VAR(&TGTJOBUSR) TYPE(*CHAR) STG(*DEFINED) LEN(10) +
         DEFVAR(&EVTDTADFND 473) /* 6.1 */
DCL        VAR(&TGTJOBNBR) TYPE(*CHAR) STG(*DEFINED) LEN(6) +
         DEFVAR(&EVTDTADFND 483) /* 6.1 */

/* Event DATA elements - variable-length data */
DCL        VAR(&PSNDPRCNAM) TYPE(*PTR)
DCL        VAR(&BSNDPRCNAM) TYPE(*CHAR) STG(*BASED) LEN(256) +
         BASPTR(&PSNDPRCNAM)
DCL        VAR(&SNDPRCNAM) TYPE(*CHAR) LEN(256)

DCL        VAR(&PRCVPRCNAM) TYPE(*PTR)
DCL        VAR(&BRCVPRCNAM) TYPE(*CHAR) STG(*BASED) LEN(256) +
         BASPTR(&PRCVPRCNAM)
DCL        VAR(&RCVPRCNAM) TYPE(*CHAR) LEN(256)

DCL        VAR(&PMSGCMPDTA) TYPE(*PTR)
DCL        VAR(&BMSGCMPDTA) TYPE(*CHAR) STG(*BASED) LEN(72) +
         BASPTR(&PMSGCMPDTA)
DCL        VAR(&MSGCMPDTA) TYPE(*CHAR) LEN(72)

DCL        VAR(&PMSGRPLDTA) TYPE(*PTR)
DCL        VAR(&BMSGRPLDTA) TYPE(*CHAR) STG(*BASED) LEN(512) +
         BASPTR(&PMSGRPLDTA)
DCL        VAR(&MSGRPLDTA) TYPE(*CHAR) LEN(512)

/* Job attributes */
DCL        VAR(&WCHJOBNAM) TYPE(*CHAR) LEN(10)
DCL        VAR(&WCHJOBUSR) TYPE(*CHAR) LEN(10)
DCL        VAR(&WCHJOBNBR) TYPE(*CHAR) LEN(6)

/* Copy parameter to work data */
CHGVAR     VAR(&EVTDTADFND) VALUE(&EVTDTA)

/* Set pointers to variable-length data */
/* Sending procedure name */
CHGVAR     VAR(&PSNDPRCNAM) VALUE(%ADDR(&EVTDTADFND))
CHGVAR     VAR(%OFS(&PSNDPRCNAM)) VALUE(%OFS(&PSNDPRCNAM) + &OFSSNDPRC)

IF         COND(&LENSNDPRC *GT 0) THEN(DO)
CHGVAR     VAR(&SNDPRCNAM) VALUE(%SST(&BSNDPRCNAM 1 &LENSNDPRC))
ENDDO

/* Receiving procedure name */
CHGVAR     VAR(&PRCVPRCNAM) VALUE(%ADDR(&EVTDTADFND))
CHGVAR     VAR(%OFS(&PRCVPRCNAM)) VALUE(%OFS(&PRCVPRCNAM) + &OFSRCVPRC)

IF         COND(&LENSNDPRC *GT 0) THEN(DO)
CHGVAR     VAR(&RCVPRCNAM) VALUE(%SST(&BRCVPRCNAM 1 &LENRCVPRC))
ENDDO

/* Message compare data */
CHGVAR     VAR(&PMSGCMPDTA) VALUE(%ADDR(&EVTDTADFND))
CHGVAR     VAR(%OFS(&PMSGCMPDTA)) VALUE(%OFS(&PMSGCMPDTA) + &OFSCMPDTA)

IF         COND(&LENSNDPRC *GT 0) THEN(DO)
CHGVAR     VAR(&MSGCMPDTA) VALUE(%SST(&BMSGCMPDTA 1 &LENCMPDTA))
ENDDO

/* Message replacement data */
CHGVAR     VAR(&PMSGRPLDTA) VALUE(%ADDR(&EVTDTADFND))
CHGVAR     VAR(%OFS(&PMSGRPLDTA)) VALUE(%OFS(&PMSGRPLDTA) + &OFSRPLDTA)

IF         COND(&LENSNDPRC *GT 0) THEN(DO)
CHGVAR     VAR(&MSGRPLDTA) VALUE(%SST(&BMSGRPLDTA 1 &LENRPLDTA))
ENDDO

/* Here is where the action happens. Some things */
/* that might be done are to print the job log,  */
/* print a dump of this program, check object    */
/* locks, etc. This all depends on the kind of   */
/* message that is defined in the watch.         */

/* Print job log where error occurred */
DSPJOBLOG  JOB(&JOBNBR/&JOBUSR/&JOBNAM) OUTPUT(*PRINT)

/* Dump the variables in this program */
DMPCLPGM

/* Notify system operator that error occurred */
/* and point to spooled output from this job  */
RTVJOBA    JOB(&WCHJOBNAM) USER(&WCHJOBUSR) NBR(&WCHJOBNBR)
SNDPGMMSG  MSG('Error occurred in job ' *CAT &JOBNBR *TCAT '/' *CAT +
         &JOBUSR *TCAT '/' *CAT &JOBNAM *TCAT ' - WRKJOB ' *CAT +
         &WCHJOBNBR *TCAT '/' *CAT &WCHJOBUSR *TCAT '/' *CAT +
         &WCHJOBNAM *TCAT ' OPTION(*SPLF) and WRKJOB ' *CAT &JOBNBR +
         *TCAT '/' *CAT &JOBUSR *TCAT '/' *CAT &JOBNAM *TCAT ' to +
         see more information.') TOMSGQ(*SYSOPR)

/* Return blank for error-detected, */
/* so that watch is not ended       */
CHGVAR     VAR(&ERRDTCT) VALUE(' ')

ENDPGM

Still have questions? We can help. Submit a case to Technical Support.

Last Modified On: December 10, 2016