System Status Via Email
System Status Via Email
System Status Via Email
Facebook Twitter Share ThisReprints 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 administr ator (in this case "[email protected]") 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 n ame "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 informatio n 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 goto endpgmq3 dly(60) check
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 Arbetsflt 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... Show Me More More on Implementation Get help from the community Po wered by ITKnowledgeExchange.com 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 + '[email protected]' + 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
* APIErrDef Standard API error handling structure. * ************************************************************************** DQUSEC DS D ErrorBytesProvided... D D ErrorBytesAvailble... D D ErrorExceptionId... D D ErrorReserved... D DAPIError DS D APIErrorProvied... D D D APIErrorAvailble... D D APIErrorMessageID... D D APIErrorReserved... D D APIErrorInformation... D
1 5 9 16
4B 0 8B 0 15 16
LIKE( ErrorBytesProvided ) INZ( %LEN( APIError ) ) LIKE( ErrorBytesAvailble ) LIKE( ErrorExceptionId ) LIKE( ErrorReserved ) 240A
1 9 13
4B 0 12B 0 16B 0
/TITLE Huvudprogram H NOMAIN /COPY CrtUsrSpcP /TITLE CrtUsrSpc: Create User Space for OS/400 API's **************************************************************** * * CrtUsrSpc: Create User Space for OS/400 API's * **************************************************************** * P CrtUsrSpc B EXPORT * * --- Procedure Interface Definition * D CrtUsrSpc PI 1 D UsrSpcName 20 * * --- Local Variables * D ReturnCode S 1 D ObjName S 10 INZ(' ') D ObjLib S 10 INZ(' ') D UserSpace S 20 INZ(' ') D ExtraAtr S 10 INZ(' ') D UserInit S 1 INZ(' ') D UserAuth S 10 INZ('*EXCLUDE ') D UserText S 50 INZ(' ') D OS400_Cmd S 160 INZ(' ') D Cmd_Length S 15P 5 INZ(0) D True S 1 INZ( *ON ) D False S 1 INZ( *OFF ) * D BinaryField DS D UserSize 1 4B 0 INZ(50000) * * Remove "User Space" * C EVAL ObjName = %SUBST(UsrSpcName : 1 : 10 ) C EVAL ObjLib = %SUBST(UsrSpcName : 11 : 10 ) * C EVAL OS400_Cmd = 'DLTUSRSPC ' + C 'USRSPC(' + C %TRIM( ObjLib ) + C '/' + C %TRIM( ObjName ) + C ')' C EVAL Cmd_Length = %SIZE(OS400_Cmd) C CALL 'QCMDEXC' 89 C PARM OS400_Cmd C PARM Cmd_Length * * Create "User Space" * C CALL 'QUSCRTUS' C PARM UsrSpcName C PARM ExtraAtr C PARM UserSize C PARM UserInit
C C * * ReturnCode *
PARM PARM
UserAuth UserText
DLJOBINPUT ds D JobName... D D UserName... D D JobNumber... D D Status... D D UserSpace... D D UserSpaceLibrary... D D Format... D D JobType... D D Reserved01... D D Reserved02... D D* DLJOB100 ds D JobName... D D UserName... D D JobNumber... D D InternalJobId... D D Status... D D JobType... D D JobSubType... D D Reserved01... D D* DLJOB200 ds D JobName... D D UserName...
D 11 20 D JobNumber... D 21 26 D InternalJobId... D 27 42 D Status... D 43 52 D JobType... D 53 53 D JobSubType... D 54 54 D Reserved01... D 55 56 D JobInfoStatus... D 57 57 D Reserved02... D 58 60 D NumberOfFieldsReturned... D 61 64B 0 D ReturnedData... D 65 1064 D* DLJOB200KEY ds D KeyNumber01... D 1 4B 0 D NumberOfKeys... D 5 8B 0 D* DLJOBKEYINFO ds D LengthOfInformation... D 1 4B 0 D KeyField... D 5 8B 0 D TypeOfData... D 9 9 D Reserved01... D 10 12 D LengthOfData... D 13 16B 0 D KeyData... D 17 1016
qualified
qualified
* --- Prototype for API Retrive User Space * D QUSRTVUS pr extpgm( 'QUSRTVUS' ) D QRtvUserSpace... D 20 D QRtvStartingPosition... D 8B 0 D QRtvLengthOfData... D 8B 0 D QRtvReceiverVariable... D 32048 D QRtvError... D 256
* D CrtUsrSpc D UsrSpcName
PR
1 20
* --- Prototype for API Retrive List Job * D QUSLJOB pr extpgm( 'QUSLJOB' ) D QJobUserSpace... D 20 D QJobFormatName... D 8 D QJobJobName... D 26 D QFldStatus... D 10 D QFldError... D 256 D QJobType... D 1 D QNbrFldRtn... D 8B 0 D QKeyFldRtn... D 8B 0 dim( 100 )