Send an e-mail to an admin when a job gets a status of *MSGW

The following program checks to see if any iSeries jobs have a status of *MSGW

You Can View User Feedback To This Tip

The following program checks to see if any iSeries jobs have a status of *MSGW. When the job gets a status of *MSGW, the program sends an e-mail to an administrator (in this case "kent.astrom@nkv.se")

Detailed program information: If anything goes wrong, the program creates a dump and terminates.

Create a user space with module "CrtUsrSpc" (source has been included below).

Run API "QUSLJOB" to return information of iSeries job. I have used the format name "JOBL0200" to retrieve "job status" and "subsystem". Job status has "key of field = 0101" and subsystem "key of field = 1906".

Run API "QUSRTVUS" to get user space attribute

- starting position of information
- number of entries (number of jobs)

Run a loop to retrieve information on all jobs that have been loaded in the user space -- one loop for one job.

First, run API "QUSRTVUS" to retrieve information about one job. This information has been retrieved in data area "LJOB200".

Second, retrieve "key fields" in and loop.
Key field 0101 = job status
Key field 1906 = subsystem

Third, if the job has status *MSGW and e-mail is sent to an Administrator.

 
      crtrpgmod module(yourlib/crtusrspc) = create user space (source
included in prior mail)
      crtrpgmod module(yourlib/nkvr4292) = mail program

      crtpgm pgm(yourlib/nkvr4292) module(yourlib/nkvr4292
yourlib/crtusrspc) actgrp(nkv)
 
      A CL program: The program calls the program every minute.

                  pgm

      check:      call pgm(nkv4292)
                  monmsg(cpf0000)

                  dlyjob      dly(60)
                  goto        check

                  endpgmq3 


The following program sends an e-mail when a job receives a status: *MSGW with OS/400 API and user space. I have included all the /COPY sources and module sources that create "user space" (CrtUsrSpc) in text files.
 

     F****************************************************************
     F*
     F* Program: NKVR4602 Send e-mail when a job get status: *MSGW
     F*
     F****************************************************************
     F*
     F****************************************************************
     D/TITLE beskrivning arrayer, tabeller
     D****************************************************************
     D* beskrivning arrayer, tabeller
     D*--------------------------------------------------------------*
     D*
      /COPY CrtUsrSpcP
      /COPY QUsRtvUS
      /COPY QUsRtvUSP
      /COPY QUsLJob2P
      /COPY QUsLJob
      /COPY APIErrDef
      /COPY QCmdExc
     D*
     D*-----------------------------------------------------------------
     D* program status dataarea
     D*-----------------------------------------------------------------
     D*
     D PgmSts         SDS
     D   P1User              254    263
     D   W1Program       *PROC
     D*
     D*-----------------------------------------------------------------
     D* *lda - local dataarea
     D*-----------------------------------------------------------------
     D*
     D LDA           e ds                  dtaara(*lda)
     D*
     D*--------------------------------------------------------------*
     D* work fields                                                  *
     D*--------------------------------------------------------------*
     D*
     D ArbetsfÄlt      ds
     D   Snipp                        1    inz( '''' )
     D   Count                       15  0 inz(  0   )
     D   KeyCount                    15  0 inz(  0   )
     D   EndPos                      15  0 inz(  0   )
     D   JobbStatus                   4    inz( ' '  )
     D   Subsystem                   20    inz( ' '  )
     D   ReturnCode                   1    inz( ' '  )
     D   UsrSpcName                  20    inz( 'DSPJOB    QTEMP     ' )
     D   FormatName                   8    inz( ' ' )
     D   QualifedJobName...
     D                               26    inz( ' ' )
     D   JobStatus                   10    inz( ' ' )
     D   JobType                      1    inz( ' ' )
     D   NbrOfFldRtn                  8B 0 inz(  0  )
     D   KeyFldRtn                    8B 0 inz(  0  ) dim( 100 )
     D   StartingPosition...
     D                                8B 0 inz(  0  )
     D   LengthOfData...
     D                                8B 0 inz(  0  )
     D   KeyStartingPosition...
     D                                8B 0 inz(  0  )
     D   KeyLengthOfData...
     D                                8B 0 inz(  0  )
     D   ReceiverVariable...
     D                            32048
     D   OS400_Cmd                 2000    inz( ' '  )
     D   CmdLength                   15P 5 inz( %size( OS400_Cmd ) )
     D   True                         1    inz( *on  )
     D   False                        1    inz( *off )
     D*
     D****************************************************************
      /TITLE Main Line
      /free
       // *************************************************************
       // Main line code
       // -------------------------------------------------------------

       exsr CheckStatusOfJob;

       *inlr = true;
       // *************************************************************
       // check status of an job
       // -------------------------------------------------------------
       begsr CheckStatusOfJob;

       // create user space
       ReturnCode = CrtUsrSpc( UsrSpcName );
       if ReturnCode = True;
         dump;
         leavesr;
       endif;

       // run API to fill user space with information about all iSeries job
       FormatName = 'JOBL0200';
       QualifedJobName = '*ALL      ' + '*ALL      ' + '*ALL  ';
       JobStatus = '*ACTIVE';
       JobType = '*';
       NbrOfFldRtn = 2;
       KeyFldRtn( 1 ) = 0101;
       KeyFldRtn( 2 ) = 1906;
       callp QUSLJOB( UsrSpcName : FormatName  : QualifedJobName :
                      JobStatus  : APIError    :
                      JobType    : NbrOfFldRtn : KeyFldRtn         );
       if APIErrorMessageID <> ' ';
         dump;
         ReturnCode = True;
         leavesr;
       endif;

       // run API to get user space attribute
       StartingPosition = 125;
       LengthOfData = 16;
       callp QUSRTVUS( UsrSpcName   : StartingPosition  :
                       LengthOfData : ReceiverVariable  :
                       APIError                           );
       QUSA0100 = ReceiverVariable;
       if APIErrorMessageID <> ' ';
         dump;
         ReturnCode = True;
         leavesr;
       endif;

       // preperation to read from user space
       StartingPosition = QUsrSpcOffset + 1;
       LengthOfData = QUsrSpcEntrieSize;

       // read from user space
       for count = 1 to QUsrSpcEntries;
         callp QUSRTVUS( UsrSpcName   : StartingPosition  :
                         LengthOfData : ReceiverVariable  :
                         APIError                           );
         LJOB200 = ReceiverVariable;
         if APIErrorMessageID <> ' ';
           dump;
           ReturnCode = True;
           leavesr;
         endif;

         // check status of job
         JobbStatus = ' ';
         Subsystem = ' ';
         LJobKeyInfo = LJob200.ReturnedData;
         KeyStartingPosition = 1;
         KeyLengthOfData = LJobKeyInfo.LengthOfInformation;
         for keycount = 1 to LJob200.NumberOfFieldsReturned;
           LJobKeyInfo = %subst( LJob200.ReturnedData :
                                 KeyStartingPosition :
                                 KeyLengthOfData );
           KeyLengthOfData = LJobKeyInfo.LengthOfInformation;
           LJobKeyInfo = %subst( LJob200.ReturnedData :
                                 KeyStartingPosition :
                                 KeyLengthOfData );
           Endpos = LJobKeyInfo.LengthOfData;
           if     LJobKeyInfo.KeyField = 0101;
              JobbStatus = %subst( LJobKeyInfo.KeyData : 1 :  Endpos );
           elseif LJobKeyInfo.KeyField = 1906;
              Subsystem = %subst( LJobKeyInfo.KeyData : 1 : Endpos );
           endif;
           KeyStartingPosition = KeyStartingPosition + KeyLengthOfData;
         endfor;
         if Jobbstatus = 'MSGW';
            Subsystem = %trim( %subst( Subsystem : 11 : 10 ) ) + '/' +
                        %trim( %subst( Subsystem :  1 : 10 ) );
            os400_cmd = 'snddst type(*lmsg) ' +
                        'tointnet((' + snipp + 'kent.astrom@nkv.se' +
                        snipp + ')) dstd(' + snipp +
                        'Jobb med status *MSGW' +
                        snipp + ') longmsg(' + snipp +
                        'Jobbet (' +
                        %trim( LJob200.JobName ) + '/' +
                        %trim( LJob200.UserName ) + '/' +
                        %trim( LJob200.JobNumber ) +
                        ') i delsystemet ' + %trim( Subsystem ) +
                        ' har status MSGW' +
                        snipp + ')';
             monitor;
               qcmdexc ( os400_cmd : %size ( os400_cmd ) );
               on-error;
                 dump;
            endmon;
         endif;

         StartingPosition = StartingPosition + LengthOfData;

       endfor;

       endsr;
      /TITLE
 


Source codes:
APIErrDef.TXT
QCmdExc.TXT
QUsRtvUS.TXT
CRTUSRSPC.TXT
QUsLJob.TXT
QUsRtvUSP.TXT
CrtUsrSpcP.TXT
QUsLJob2P.TXT
USER FEEDBACK TO THIS TIP
  • The code for sending a message when a job is in MSGW status was fine, but it might not be suitable for many sites. MSGW status can occur for two general reasons. The status occurs when a job is waiting for a reply to an *INQ (inquiry) message, and these jobs might need operator attention. For some of those, operator attention is not needed. A job can also go to MSGW status when it is monitoring a message queue waiting for any message to arrive. It's almost never true that any user at all should be notified in those cases -- much less an operator. In the first case, I might be running a program that deliberately sends me an *INQ message and my operators would not appreciate getting e-mails when that happens -- they'd only want to be notified when the message needed their attention.
 An example for the second case would be a program that monitors the QINACTMSGQ system value message queue. That job could easily be in MSGW status at all times every day. I'm certain my operators would get irritated in a hurry if they started getting e-mails every minute of every day. Since various third-party vendors' and IBM server-style functions wait on message queues, it is necessary to determine the reason for the MSGW status. &
 


 

; Thomas Liotta

More on this topic

This was first published in December 2003

Dig deeper on Implementation

1 comment

Oldest 

Forgot Password?

No problem! Submit your e-mail address below. We'll send you an email containing your password.

Your password has been sent to:

-ADS BY GOOGLE

SearchEnterpriseLinux

SearchDataCenter

Close