Learn how to use watch support to automate system operations.
Over the last several months, I've received many notes from readers, including these:
- I have some custom routines that need to run when a Daylight Saving Time change goes into effect. How can I have these programs run automatically?
- There is one user profile that the system operator is always re-enabling.... Is there a way to automate this?
- We have a program that periodically reads QHST files to see what files need to be reorganized...maintain record sequence...based on CPF4653.... Is there a way to avoid scanning QHST?
These notes may initially appear to be unrelated, but all of these questions, and more that I haven't listed above, can be addressed by one common facility that is provided with the i operating system. That facility is the watch support introduced with V5R4. Watch support essentially allows you to tell the system that if a particular message (or list of messages) is sent to a specific message queue (or a list of message queues), then the system should call a user exit program. In the case of the three items listed above, the messages that we would be interested in are these, respectively:
-
•CPD1689--Local system time has been adjusted.
-
•CPF1393--Subsystem &1 disabled user profile &2 on device &3.
-
•CPF4653--DLTPCT parameter value for member &1 exceeded.
In this series of articles, you will see how to use watch support to automate system operations that are related to these specific messages. The three messages I have selected to use provide us with the ability to learn about various aspects of watch support. When this series of articles completes, you should be able to review the messages that are being sent on your system and determine what automation you might apply to those messages in order to streamline the running of your system. Note that there are alternative solutions available for all three questions. A watch is simply one of the tools that can be used in addressing these user requirements--a tool that I believe is currently underutilized.
To start watching for a message, you use the Start Watch (STRWCH) command. If you are currently running V5R4, refer to the STRWCH documentation found here. For V6R1, IBM enhanced the STRWCH command; the appropriate documentation for that release can be found here. The sample programs I will be developing in this series of articles will be based on the V5R4 level of support, though I will, when appropriate, make mention of V6R1 enhancements that would have made life easier for us!
The STRWCH command has several parameters. The first parameter, Session ID (SSNID), is required and allows you to name a watch session. You can use the special value *GEN to have the system generate a name, but I recommend that you provide a meaningful name based on either the message being watched or the function being performed. For instance, if CPD1689 ("Local system time has been adjusted.") is the watched-for message, then it may make sense to name the watch session something such as CPD1689 or TIME_CHG. Jumping ahead a bit, I will point out that I selected TIME_CHG rather than DST_CHG as message CPD1689 can be sent for reasons other than a Daylight Saving Time (DST) adjustment. The Cause text for CPD1689 mentions for instance that a change in the QTIMZON system value can also cause a local system time adjustment. Later, I'll show you how to distinguish between a DST-initiated time adjustment and a QTIMZON system value-initiated time adjustment.
The session name will show up in several areas of the system. When you start a watch session, the system actually starts a new job for each watch session. The session name is used for the job name portion of the new qualified job name, so it will appear on commands such as WRKACTJOB and WRKSBMJOB. There are also watch-related commands, such as End Watch (ENDWCH) and Work with Watches (WRKWCH), that use the Session ID to identify a watch session. Using a meaningful session name can simplify your life when working with jobs on the system. While each started watch is a separate job on your system, you should not be too concerned. The watch exit program will not consume any CPU unless a watched-for message is sent. From a limits point of view, you can have up to 10,000 watches concurrently started on a system.
A second required parameter of the STRWCH command is the Watch program (WCHPGM). This parameter identifies the user exit program to call when a watch condition is met. We will look at how to develop these user exit programs in great detail throughout this series of articles.
The other parameters of the STRWCH command are optional. Below, I call out those optional parameters that we will be using in our review of the watch support.
One optional parameter that we will be using is Watch for message (WCHMSG). This parameter allows you to specify up to five watched-for message identifiers. If you need more than five messages in one session, the Start Watch (QSCSWCH) API documented here for V5R4 allows you to specify up to 100 messages.
In addition to specifying what message(s) to watch for, the WCHMSG parameter also allows you to provide comparison data for further filtering on when the exit program should be called. Comparison data allows you to tell the system to not just call the exit program when a particular message is sent, but to only call the exit program when a particular message is sent and when replacement data associated with the message being sent contains a specific text string. We will not be using this comparison data feature in the watch session for CPD1689 but will revisit this capability when watching for the message CPF1393 in the third article of this series.
You might have been surprised to see that the watched-for messaged IDs are optional when starting a watch. The reason is that you can start a watch for system activity other than just messages. You can, for instance, start a watch for a particular Licensed Internal Code (LIC) log entry or, using one of the V6R1 enhancements, for a Product Activity Log (PAL) entry. We will not be looking any further at LIC log entries or PAL entries as most users will never start a watch for these types of activities on the system, but I do want to point them out as a few users may want to take advantage of this support. It is this generalized nature of watch support that causes the system exit point to be named "Watch for Event" rather than "Watch for Message."
For the same reason WCHMSG is optional, the Watch message queue (QCHMSGQ) parameter of STRWCH is also optional. This parameter, when watching for a message, allows you to indicate where to watch for the message. There are special values such as *SYSOPR for the system operator message queue QSYSOPR in library QSYS, *HSTLOG for the QHST message queue, and *JOBLOG for messages sent to jobs on the system. Additionally, you can provide the name of a specific message queue.
As an aside for those of you who may currently be searching QHST history files for various messages, with watch support the exit program is called when the message is sent to the QHST queue. This provides for a more real-time notification of the message and, from a performance point of view, does not require the system to copy any messages to the QHST log files.
Likewise, while we will not be using the *JOBLOG watch support, you should be aware that you can watch for a message being sent to the job log of a specific job, a list of up to five jobs, *ALL jobs, or jobs identified generically based on the job and/or user name. A very powerful real-time monitor for job-related problems...
With this brief introduction to the STRWCH command, and due to being out of room for this month's article, the following program WCHCPD1689 is shown and could be used as a watch exit program for message CPD1689.
dWchCPD1689 pr extpgm('WCHCPD1689')
d Type 10 const
d SsnID 10 const
d Error 10
d MsgDta likeds(ESCQWFM)
dWchCPD1689 pi
d Type 10 const
d SsnID 10 const
d Error 10
d MsgDta likeds(ESCQWFM)
/copy qsysinc/qrpglesrc,escwcht
dCPD1689 ds based(RplDtaPtr)
d qualified
d MinutesAdj 10i 0
d ReasonCode 5i 0
dRplDtaPtr s *
dRqdNbrParms c 4
dSessionName c 'TIME_CHG '
dSeePrvMsgs c 0
dDSTChg c 1
dSysValChg c 2
/free
monitor;
// Check to make sure program environment is as expected
if %parms < RqdNbrParms;
dsply ('WCHCPD1689 received only ' +%char(%parms) + ' parms');
*inlr = *on;
return;
endif;
if Type <> '*MSGID';
dsply ('WCHCPD1689 received type ' + Type);
Error = '*ERROR';
*inlr = *on;
return;
endif;
if SsnID <> SessionName;
dsply ('WCHCPD1689 received SsnID ' + SsnID);
Error = '*ERROR';
*inlr = *on;
return;
endif;
if MsgDta.ESCMID00 <> 'CPD1689';
dsply ('WCHCPD1689 received message ' + MsgDta.ESCMID00);
Error = '*ERROR';
*inlr = *on;
return;
endif;
// Everything looks OK so get message replacement data
RplDtaPtr = %addr(MsgDta) + MsgDta.ESCORD;
// Take appropriate action based on reason code
select;
when CPD1689.ReasonCode = SeePrvMsgs;
// Examine previous messages in QSYSOPR
when CPD1689.ReasonCode = DSTChg;
// Do processing necessary for DST transition
when CPD1689.ReasonCode = SysValChg;
// Do any processing needed for QTIMZON change
other;
dsply ('WCHCPD1689 Reason code ' +
%char(CPD1689.ReasonCode));
endsl;
// Set normal end of processing
Error = *blanks;
return;
on-error;
Error = '*ERROR';
*inlr = *on;
return;
endmon;
/end-free
To compile this program into library VINING, you would use this command:
CRTBNDRPG PGM(VINING/WCHCPD1689)
To start a watch session named TIME_CHG, specifying WCHCPD1689 as the exit program, for message CPD1689 being sent to QHST, you would use this command:
STRWCH SSNID(TIME_CHG) WCHPGM(VINING/WCHCPD1689) WCHMSG((CPD1689))
WCHMSGQ((*HSTLOG))
To end the watch session named TIME_CHG, use this command:
ENDWCH SSNID(TIME_CHG)
In the next article, we'll look at the details behind what program WCHCPD1689 is doing. If you are interested in understanding how the program works prior to that, you can start your research with the V5R4 Watch for Event exit program documentation found here. This documentation is where we'll resume in the next article.
Before closing though, I would like to discuss my use of the dsply operation in the WCHCPD1689 program. As this article is attempting to introduce watches, and not the proper way to report errors, I have minimized the amount of code in WCHCPD1689 by the use of dsply. My intent is to simply show where error conditions might appear during the processing of a watch exit program. A production-level program should use predefined messages that document appropriate recovery actions, ensure that the messages get logged where support personnel can be easily made aware of the error situation (right now, the dsply messages will be going to QSYSOPR as the watch exit program is running in a batch job), etc. Come to think of it, a discussion of the message handler APIs would make for a good column (or two) in the future....
Meanwhile, if you have other API questions, send them to me at
LATEST COMMENTS
MC Press Online