顯示具有 JOBLOG 標籤的文章。 顯示所有文章
顯示具有 JOBLOG 標籤的文章。 顯示所有文章

星期三, 11月 08, 2023

2009-07-01 如何檢核某 Job 有含所指定的 MSGID, 並取得該訊息的(MSGDTA)欄位資料(Command CHKJLMSGID)?


如何檢核某 Job 有含所指定的 MSGID, 並取得該訊息的(MSGDTA)欄位資料(Command CHKJLMSGID)?

先前有 Commamd CHKJOBLOG(利用 QMHLJOBL List Job Log API)來檢核 joblog,並將該訊息傳送到指定的 MSGQ,
此次以 QGYOLJBL Open list of joblog messages API 來檢核所指定的 MSGID是否存在,並回傳該訊息相關資訊是否空白來確認 MSGID 是否存在?
空白表不存在。


File  : QRPGLESRC
Member: CHKJLMSGID
Type  : RPGLE
OS version: V5R1 以上
Usage : CRTBNDRPG CHKJLMSGID TGTRLS(V5R1M0)

     **
     **  Program . . : CHKJLMSGID
     **  Description : Check Joblog by MsgId
     **  Author  . . : Vengoal Chang
     **  Published . : Dimerco Data System Corporation
     **  Date  . . . : July  1, 2009
     **
     **
     **  Program summary
     **  ---------------
     **
     **  Message handling API:
     **    QGYOLJBL      Open list of joblog   Lists messages from the specified
     **                  messages              job's joblog in sending data and
     **                                        time order. Replies to inquiry-
     **                                        messages are listed immediately
     **                                        after the message it is associated
     **                                        with.
     **
     **                                        The QGYOLJBL API is found in the
     **                                        QGY library as are all other open
     **                                        list APIs - prior to V5R3.
     **
     **                                        To retrieve open lists entries
     **                                        from an already open list the
     **                                        QGYGTLE (Get List Entries) API
     **                                        is available.
     **
     **  Open list APIs:
     **    QGYGTLE       Get list entries      To retrieve open lists entries
     **                                        from an already open list the
     **                                        QGYGTLE (Get List Entries) API
     **                                        is available.
     **
     **    QGYCLST       Close list            This API closes the previously
     **                                        opened list identified by the
     **                                        request handle parameter.
     **                                        Storage allocated is freed.
     **
     **  Sequence of events:
     **    1. The API input parameters are initialized
     **
     **    2. The open list of joblog messages API is called
     **
     **    3. If an error occurred calling the API or
     **       no entry is found blanks are returned to
     **       the caller
     **
     **    4. The most recent secified message id joblog message
     **       data is retrieved and returned to the caller.
     **
     **
     **  Parameters:
     **    PxJobId     INPUT      Qualified job name of the job whose joblog
     **                           messages are to be listed. The following
     **                           format applies:
     **
     **                            1-10  Char 10   Job name
     **                           11-20  Char 10   Job user
     **                           21-26  Char  6   Job number
     **
     **                           The special value '*' is allowed. This value
     **                           identifies the current job.
     **
     **    PxMsgF      OUTPUT     The MSGF   of the most recent found msgid
     **                           is returned.  If no msgid found blanks
     **                           are returned.
     **
     **    PxMsgFLib   OUTPUT     The MSGFLIB of the most recent found msgid
     **                           is returned.  If no msgid found blanks
     **                           are returned.
     **
     **    PxMsgDta    OUTPUT     The MSGDTA of the most recent found msgid
     **                           is returned.  If no msgid found blanks
     **                           are returned.
     **
     **
     **  Programmer's note:
     **    As mentioned above library QGY must be in the job library list
     **    to succesfully run this program on releases prior to V5R3.
     **
     **    To list another user's joblog *JOBCTL special authority is
     **    required.
     **
     **    To list the joblog of a user having user class *SECOFR, special
     **    authority *ALLOBJ is required.
     **
     **
     **  Compile options:
     **
     **   CrtRpgMod  Module( CHKJLMSGID )
     **
     **   CrtPgm     Srvpgm( CHKJLMSGID )
     **              Module( CHKJLMSGID )
     **              ActGrp( QILE )
     **
     **
     **-- Control spec:  -----------------------------------------------------**
     H Option( *SrcStmt ) DftActGrp(*NO)
     **-- API error data structure:  -----------------------------------------**
     D ERRC0100        Ds                  Qualified
     D  BytPrv                       10i 0 Inz( %Size( ERRC0100 ))
     D  BytAvl                       10i 0
     D  MsgId                         7a
     D                                1a
     D  MsgDta                      128a
     **-- API parameters:  ---------------------------------------------------**
     D RtnRcdNbr       s             10i 0
     **
     D SltInf          Ds                  Qualified
     D  RtvDrc                       10a
     D  JobId                        26a   Inz( '*' )
     D  IntJobId                     16a
     D  StrKey                        4a
     D  MsgLenMax                    10i 0 Inz( -1 )
     D  HlpLenMax                    10i 0 Inz( 0 )
     D  FldIdsOfs                    10i 0 Inz( 84 )
     D  FldIdsNbr                    10i 0 Inz( %Elem( SltInf.FldIds ))
     D  CalMsqOfs                    10i 0 Inz( 88 )
     D  CalMsqLen                    10i 0 Inz( 1 )
     D                                4a
     D  FldIds                       10i 0 Dim( 1 ) Inz( 201 )
     D  CalMsq                       10a   Inz( '*' )
     **
     D LstInf          Ds                  Qualified
     D  RcdNbrTot                    10i 0
     D  RcdNbrRtn                    10i 0
     D  Handle                        4a
     D  RcdLen                       10i 0
     D  InfSts                        1a
     D  TimStp                       13a
     D  LstSts                        1a
     D                                1a
     D  InfLen                       10i 0
     D  Rcd1                         10i 0
     D                               40a
     **
     D OLJL0100        Ds         32767    Qualified
     D  NxtMsgOfs                    10i 0
     D  FldDtaOfs                    10i 0
     D  FldNbrOfs                    10i 0
     D  MsgSev                       10i 0
     D  MsgId                         7a
     D  MsgTyp                        2a
     D  MsgKey                        4a
     D  MsgF                         10a
     D  MsgFlib                      10a
     D  DatSnt                        7a
     D  TimSnt                        6a
     D  MicSec                        6a
     **
     D FldDta          Ds                  Qualified  Based( pFldDta )
     D  NxtFldOfs                    10i 0
     D  FldDtaLen                    10i 0
     D  FldId                        10i 0
     D  DtaTyp                        1a
     D  DtaSts                        1a
     D                               14a
     D  DtaLen                       10i 0
     D  Dta                        1024a

     **-- Open list of job log messages:
     D LstLogMsg       Pr                  ExtPgm( 'QGYOLJBL' )
     D  LlRcvVar                  65535a          Options( *VarSize )
     D  LlRcvVarLen                  10i 0 Const
     D  LlLstInf                     80a
     D  LlNbrRcdRtn                  10i 0 Const
     D  LlLogSltInf                1024a   Const  Options( *VarSize )
     D  LlLogSltLen                  10i 0 Const
     D  LlError                    1024a          Options( *VarSize )
     **-- Get list entry:
     D GetLstEnt       Pr                  ExtPgm( 'QGYGTLE' )
     D  GlRcvVar                  65535a          Options( *VarSize )
     D  GlRcvVarLen                  10i 0 Const
     D  GlHandle                      4a   Const
     D  GlLstInf                     80a
     D  GlNbrRcdRtn                  10i 0 Const
     D  GlRtnRcdNbr                  10i 0 Const
     D  GlError                    1024a          Options( *VarSize )
     **-- Close list:
     D CloseLst        Pr                  ExtPgm( 'QGYCLST' )
     D  ClHandle                      4a   Const
     D  ClError                    1024a          Options( *VarSize )

     D CmdStr          S           1024    INZ
     D CmdLen          S             15P 5 INZ(1024)
     **-- Call system command:
     D  QCMDEXC        PR                  ExtPgm('QCMDEXC')
     D   Cmd                        500A   options(*varsize) Const
     D   CmdLen                      15P 5 Const


     D CHKJLMSGID      Pr
     D  PxJobId                      26a
     D  PxMsgId                       7a
     D  PxMsgF                       10a
     D  PxMsgFLib                    10a
     D  PxMsgDta                    256a
     **
     D CHKJLMSGID      Pi
     D  PxJobId                      26a
     D  PxMsgId                       7a
     D  PxMsgF                       10a
     D  PxMsgFLib                    10a
     D  PxMsgDta                    256a

      /Free

        CmdStr = 'ADDLIBLE QGY' ;
        CmdLen = %len(%trim(CmdStr));
        Monitor;
        QCMDEXC(%trim(CmdStr) : CmdLen);
        On-Error;
        EndMon;

        PxMsgF    = *Blanks;
        PxMsgFLib = *Blanks;
        PxMsgDta  = *Blanks;

        SltInf.JobId  = PxJobId;
        SltInf.RtvDrc = '*PRV';
        SltInf.StrKey = x'FFFFFFFF';

        LstLogMsg( OLJL0100
                 : %Size( OLJL0100 )
                 : LstInf
                 : 1
                 : SltInf
                 : %Size( SltInf )
                 : ERRC0100
                 );

        If  ERRC0100.BytAvl = *Zero;

          DoW  LstInf.LstSts <> '2'  Or  LstInf.RcdNbrTot >= RtnRcdNbr;

            pFldDta = %Addr( OLJL0100 ) + OLJL0100.FldDtaOfs;

            If  OLJL0100.MsgId = PxMsgId  ;

              PxMsgF   = OLJL0100.MsgF;
              PxMsgFLib= OLJL0100.MsgFLib;
              PxMsgDta = %Subst( FldDta.Dta: 1: FldDta.DtaLen );
              Leave;
            EndIf;

            RtnRcdNbr += 1;

            GetLstEnt( OLJL0100
                     : %Size( OLJL0100 )
                     : LstInf.Handle
                     : LstInf
                     : 1
                     : RtnRcdNbr
                     : ERRC0100
                     );

            If  ERRC0100.BytAvl > *Zero;
              Leave;
            EndIf;
          EndDo;

          CloseLst( LstInf.Handle: ERRC0100 );
        EndIf;

        *InLr = *On;
        Return;

      /End-Free


File  : QCMDSRC
Member: CHKJLMSGID
Type  : CMD
Usage : CRTCMD CHKJLMSGID ALLOW(*IPGM *BPGM)


/********************************************************************/
/*   Title:      CHKJLMSGID: Check JobLog by MsgId                  */
/*                                                                  */
/*   Description - This command performs job log checked by MSGID   */
/*                                                                  */
/*   The Create Command command should include the following:       */
/*                                                                  */
/*           CRTCMD     CMD(CHKJLMSGID) PGM(CHKJLMSGID)             */
/*                                                                  */
/********************************************************************/
      /*------------------------------------------------*/
      /*  Command Definition                            */
      /*------------------------------------------------*/

             CMD        PROMPT('Check JobLog by MsgID')
             PARM       KWD(JOB) +
                        TYPE(Q10DD) +
                        DFT(*) +
                        SNGVAL( +
                          (* )) +
                        KEYPARM(*YES) +
                        PROMPT('Job name' 1)
             PARM       KWD(MSGID) TYPE(*CHAR) LEN(7) SPCVAL((*ALL)) +
                          MIN(1) PROMPT('Message ID to be checked')
             PARM       KWD(MSGF) TYPE(*CHAR) LEN(10) +
                          RTNVAL(*YES) PROMPT('CL var for +
                          MSGF         (10)')
             PARM       KWD(MSGFLIB) TYPE(*CHAR) LEN(10) +
                          RTNVAL(*YES) PROMPT('CL var for +
                          MSGFLIB      (10)')
             PARM       KWD(MSGDTA) TYPE(*CHAR) LEN(256) +
                          RTNVAL(*YES) PROMPT('CL var for +
                          MSGDTA      (256)')
Q10DD:       QUAL       TYPE(*NAME) +
                        LEN(10) +
                        MIN(1) +
                        EXPR(*YES)
             QUAL       TYPE(*NAME) +
                        LEN(10) +
                        EXPR(*YES) +
                        PROMPT('User')
             QUAL       TYPE(*CHAR) +
                        LEN(6) +
                        RANGE( +
                          '000000' +
                          '999999') +
                        FULL(*YES) +
                        EXPR(*YES) +
                        PROMPT('Number')



File  : QCLSRC
Member: CHKJLMSGT
Type  : CLP
Usage : CRTCLPGM CHKJLMSGT
        Testing sample source


PGM
     DCL &MSGF    *CHAR  10
     DCL &MSGFLIB *CHAR  10
     DCL &MSGDTA  *CHAR 256
     DCL &MSGID   *CHAR   7
     DCL &MSGTXT  *CHAR 256

             CHGVAR &MSGID 'CPIAD02'
             CHKJLMSGID JOB(291419/QUSER/QZDASOINIT) MSGID(&MSGID) +
                          MSGF(&MSGF) MSGFLIB(&MSGFLIB) MSGDTA(&MSGDTA)
             IF (&MSGF *NE ' '    ) DO
             SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
                          MSGDTA(&MSGDTA)
             ENDDO

             CHGVAR &MSGID 'AMQ7163'
             CHKJLMSGID JOB(295970/QMQM/AMQZLAA0) MSGID(&MSGID) +
                          MSGF(&MSGF) MSGFLIB(&MSGFLIB) MSGDTA(&MSGDTA)
             IF (&MSGF *NE ' '    ) DO
             SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
                          MSGDTA(&MSGDTA)
             RTVMSG     MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
                          MSGDTA(&MSGDTA) MSG(&MSGTXT)
             SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSGTXT)
             ENDDO

             CHGVAR &MSGID 'CPC1221'
             CHKJLMSGID JOB(288243/FUND/TRI603Q2) MSGID(&MSGID) +
                          MSGF(&MSGF) MSGFLIB(&MSGFLIB) MSGDTA(&MSGDTA)
             IF (&MSGF *NE ' '    ) DO
             SNDPGMMSG  MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
                          MSGDTA(&MSGDTA)
             ENDDO
ENDPGM




2008-05-16 如何取得 Job 狀態為 MSGW 的程式錯誤訊息,並傳送程式錯誤訊息給指定使用者?(Command RTVMSGWJL with API QMHLJOBL)


如何取得 Job 狀態為 MSGW 的程式錯誤訊息,並傳送程式錯誤訊息給指定使用者?(Command RTVMSGWJL with API QMHLJOBL)

你可以先使用 API QUSLJOB 取得所有 Job 的列表,再篩選 Job 狀態為 MSGW 的 Job 執行 RTVMSGWJL 指令即可。


File   : QRPGLESRC
Member : RTVMSGWJLR
Type   : RPGLE
Usage  : CRTBNDCL PGM(RTVMSGWJL) 
OS Version: V5R1 以上


     H DFTACTGRP(*NO) ACTGRP(*CALLER) BNDDIR('QC2LE') EXPROPTS(*RESDECPOS)
     H DATFMT(*ISO)   TIMFMT(*ISO)    DEBUG
     H OPTION(*SRCSTMT:*NODEBUGIO)
      *----------------------------------------------------------------
      * RTVMSGWJL  Retrieve Job MSGW ErrMsg from Job Log
      * Copyright (C) 04/03/2008  Vengoal Chang    
      * This program is free software, you can redistribute it and/or modify it under the terms
      * of the GNU General Public License as published by the Free Software Foundation.
      *
      *----------------------------------------------------------------
      * This program retrieve specified job job's log and send err log
      * to specified MSGQ, you could modify for checking message
      * type or message id as your request.
      *----------------------------------------------------------------
      * api (application program interfaces) used:
      * quscrtus  create user space
      * qusptrus  retrieve pointer to user space
      * qmhljobl  list job log messages
      * qezsndmg  send message to user
      *----------------------------------------------------------------
     D uSpaceName      s             20    inz('RTVMSGWJL QTEMP     ')
     D msgtxt          s            768
     D msgtxt494       s            494
     D msgtxt06        s            256
     D msgtxt15        s            256
     D msgtxt17        s            256
     D QUSLIB          s             10

     D MsgQDs          Ds
     D  MsgQEntSize                   4B 0
     D  MsgQEntStr                   20    Dim( 20 )
     D Idx             S              2  0
     D AryIdx          S             10I 0
     D QualMsgq        DS
     D   MsgQ                        10
     D   MsgQLib                     10

      *Array for contain MsgQStr
     D MsgQUsrDs       Ds
     D MsgQUsrAry                    10    Dim( 20 )
     D                                     Inz( *HiVal )    Ascend
      *  -------------------------------------------------------------------
      *  -  User space attributes data structure                           -
      *  -------------------------------------------------------------------

     D QUSAttr         DS
     D  QUSNumRec                    10I 0 Inz( 1 )
     D  QUSKey                       10I 0 Inz( 3 )
     D  QUSRecLen                    10I 0 Inz( 1 )
     D  QUSRecData                    1A   Inz( '1' )

      *----------------------------------------------------------------
      * Get user space list info from header section.
      *----------------------------------------------------------------
     D                 ds                  based(uHeadPtr)
     D uOffSetToList         125    128i 0
     D uNumOfEntrys          133    136i 0
     D uSizeOfEntry          137    140i 0
      *
     D uListEntry1     ds                  Based(uListPtr )
     D uOffsetToNext                 10i 0 overlay(uListEntry1:1)
     D uOffsetToFlds                 10i 0 overlay(uListEntry1:5)
     D uNumFldsRetrnd                10i 0 overlay(uListEntry1:9)
     D uMsgSeverity                  10i 0 overlay(uListEntry1:12)
     D uMsgId                         7a   overlay(uListEntry1:17)
     D uMsgType                       2a   overlay(uListEntry1:24)
     D uMsgKey                        4a   overlay(uListEntry1:26)
     D uMsgFile                      20a   overlay(uListEntry1:30)
     D uMsgFileName                  10a   overlay(uListEntry1:30)
     D uMsgFileLib                   10a   overlay(uListEntry1:40)
      * these fields repeat for each key selected.
     D uListEntry2     ds                  Based(uListPtr2)
     D u2OffsetToNext                10i 0
     D u2LengthOfFlds                10i 0
     D u2IdentifierF                 10i 0
     D u2TypeOfData                   1a
     D u2StatOfData                   1a
     D u2Reserved                    14a
     D u2LengthOfData                10i 0
     D u2Data                       500
      *----------------------------------------------------------------
      * Error return code parm for APIs.
      *----------------------------------------------------------------
     D vApiErrDs       ds
     D  vbytpv                       10i 0 inz(%size(vApiErrDs))
     D  vbytav                       10i 0 inz(0)
     D  vmsgid                        7a
     D  vresvd                        1a
     D  vrpldta                      50a
      *
      *----------------------------------------------------------------
      * Message selection data structure.
      *
      *                               Retrieve JOB Log direction
      *-----------------------------|-------------|--------------------
      * Parameter                   | From Top    | From Bottom
      *-----------------------------|-------------|--------------------
      * msListDirection             | *NEXT       | *PRV
      * msStartingMessageKey        | X'00000000' | X'FFFFFFFF'
      *----------------------------------------------------------------
     D MsgSelectDS     ds
     D  msMaxMsgRequested...
     D                               10i 0 inz(-1)     overlay(msgSelectDS:1)   num of msg requested
     D  msListDirection...
     D                               10a   inz('*NEXT') overlay(msgSelectDS:5)   List direction
     D  msQualifiedJobName...
     D                               10a   inz('*')    overlay(msgSelectDS:15)     * = current job
     D  msQualifiedUserName...
     D                               10a   inz(' ')    overlay(msgSelectDS:25)       = current job
     D  msQualifiedJobNumber...
     D                                6a   inz(' ')    overlay(msgSelectDS:35)       = current job
     D  msInternalJobIdentifier...
     D                               16a   inz(' ')    overlay(msgSelectDS:41)       = current job
     D  msStartingMessageKey...
     D                                4a   inz(x'00000000')                     start newest message
     D                                                 overlay(msgselectDS:57)
     D  msMaxMsgLength...
     D                               10i 0 inz(500)    overlay(msgSelectDS:61)  id 301,302 lengths
     D  msMaxMsgHelpLength...
     D                               10i 0 inz(100)    overlay(msgSelectDS:65)  id 401,402,403,404
     D  msOffsetToIdentifiersOfFieldstoReturn...
     D                               10i 0 inz(84)     overlay(msgSelectDS:69)  to start of array
     D  msNumberOfFieldsToReturn...
     D                               10i 0 inz(1)      overlay(msgSelectDS:73)
     D  msOffsetToCallMsgQname...
     D                               10i 0 inz(88)     overlay(msgSelectDS:77)
     D  msLengthOfCallMsgQname...
     D                               10i 0 inz(1)      overlay(msgSelectDS:81)
     D  msIndentifiersOfFieldsToReturn...
     D                               10i 0 inz(0302)   overlay(msgSelectDS:85)
     D  msCallMessageQueueName...
     D                                1a   inz('*')    overlay(msgSelectDS:89)
      *----------------------------------------------------------------
      * Create Prototypes for calls
      * --------------------------------------------------------------------
      *  -  QusCrtUs  - Create User Space API                              -
      *  -                                                                 -
      *  -  Usage      Length   Type         Parameter Description         -
      *  -                                                                 -
      *  -  Input          20   Character    Qualified user space name     -
      *  -  Input          10   Character    Extended attribute            -
      *  -  Input         4 0   Binary       Initial size                  -
      *  -  Input           1   Character    Initial value                 -
      *  -  Input          10   Character    Public authority              -
      *  -  Input          50   Character    Text description              -
      *  -  Replace        10   Character    Replace                       -
      * --------------------------------------------------------------------
     D quscrtus        PR                  ExtPgm('QUSCRTUS')
     D                               20
     D                               10    const
     D                               10i 0 const
     D                                1    const
     D                               10    const
     D                               50    const
     D                               10    const
     Db                                    like(vApiErrDS)
      *  -------------------------------------------------------------------
      *  -  Qusptrus      - Get user space pointer       API               -
      *  -                                                                 -
      *  -  Usage      Length   Type         Parameter Description         -
      *  -                                                                 -
      *  -  Input          20   Character    Qualified user space name     -
      *  -  Output          *   Pointer      UserSpace Pointer             -
      *  -  Output                           Error Code                    -
      *  - -----------------------------------------------------------------
     D qusptrus        PR                  ExtPgm('QUSPTRUS')                   retrieve pointer
     D                               20                                         Space Name
     D                                 *                                        pointer
     Db                                    like(vApiErrDS)                      error parm
      *  -------------------------------------------------------------------
      *  -  Quscusat      - Change User Space Attributes API               -
      *  -                                                                 -
      *  -  Usage      Length   Type         Parameter Description         -
      *  -                                                                 -
      *  -  Output         10   Character    Returned library              -
      *  -  Input          20   Character    Qualified user space name     -
      *  -  Input          13   Character    Attribute structure           -
      *  -  Output                           Error code                    -
      *  -------------------------------------------------------------------
     D quscusat        PR                  ExtPgm( 'QUSCUSAT' )
     D                               10A   Const
     D                               20A   Const
     D                               13A   Const
     Db                                    like(vApiErrDS)
      *  ---------------------------------------------------------------
     D system          PR            10I 0 extproc('system')
     D  i_cmd                          *   value options(*string)
      *
     D EXCP_MSGID      S              7A   import('_EXCP_MSGID')
      *  --------------------------------------------------------------
     D qmhljobl        PR                  ExtPgm('QMHLJOBL ')
     D                               20
     D                                8    const
     Db                                    like(MsgSelectDS)
     D                               10i 0 const
     D                                8    const
     Db                                    like(vApiErrDS)
      *  --------------------------------------------------------------
     D qmhsndm         PR                  ExtPgm('QMHSNDM')
     D  msgid                         7    const
     D  msgfil                       20    const
     D  msgtxt                      256    const
     D  msglen                       10i 0 const
     D  msgtype                      10    const
     D  msgq                         10    const
     D  msgq#                        10i 0 const
     D  rpymq                        20    const
     D  msgkey                        4    const
     Db                                    like(vApiErrDS)
      *  --------------------------------------------------------------
     D QEZSNDMG        PR                  ExtPgm('QEZSNDMG')
     D   Msgtype                     10A   const
     D   DelivMode                   10A   const
     D   MsgTxt                   32767A   const options(*varsize)
     D   MsgLen                      10I 0 const
     D   MsgQ                        10A   const
     D                                     dim(32767) options(*varsize)
     D   NumMsgQ                     10I 0 const
     D   MsgSent                     10I 0
     D   FuncReq                     10I 0
     D   ErrorCode                32767A   options(*varsize)
     D   DspScrn                      1A   const options(*nopass)
     D   ReplyQ                      20A   const options(*nopass)
     D   NameType                     4A   const options(*nopass)
     D   CCSID                       10I 0 const options(*nopass)

     D ErrorCode       DS
     D   BytesProv                   10I 0 inz(0)
     D   BytesAvail                  10I 0 inz(0)

     D msgTypeA        s             10
     D sentcode        s             10I 0
     D funccode        s             10I 0

     D main            PR                  extpgm('RTVMSGWJLR')
     D  jobname                      10
     D  jobuser                      10
     D  jobnumber                     6
     D  msgtype                       5
     D  msgQDsInput                        like(MsgQDs)

     D main            PI
     D  jobname                      10
     D  jobuser                      10
     D  jobnumber                     6
     D  msgtype                       5
     D  msgQDsInput                        like(MsgQDs)

      *----------------------------------------------------------------
      * Main Process
      *----------------------------------------------------------------
     C                   eval      *inlr = *on

     C                   eval      msQualifiedJobName   = jobname
     C                   eval      msQualifiedUserName  = jobuser
     C                   eval      msQualifiedJobNumber = jobnumber
     c                   eval      msgTypeA = MsgType
     C                   eval      msgQDs  = msgQDsInput

     C                   Eval      Idx = 0
     C                   Eval      AryIdx = 0
     C                   DoW       Idx < MsgQEntSize
     C                   Eval      Idx = Idx + 1
     C                   Eval      QualMsgQ  = MsgQEntStr(Idx)
      * only msgq show onec
      * regardless of number times used.
     C                   If        AryIdx = 0  or
     C                             %lookup(MsgQ :MsgQUsrAry:1:AryIdx) = 0
     C                   Eval      AryIdx = AryIdx + 1
     C                   Eval      MsgQUsrAry(AryIdx)  = MsgQ
     C                   EndIf

     C                   EndDo

      *----------------------------------------------------------------
      * Create user space
     C                   callp     QUSCRTUS(
     C                             uSpaceName:
     C                             'TEST':
     C                             1500000:
     C                             x'00':
     C                             '*ALL':
     C                             'User Space CHKJOBLOG' :
     C                             '*YES':
     C                             vApiErrDs)
      * set UserSpace to autoextended
     C                   CallP     QUSCUSAT( QUSLib     :
     C                                       uSpaceName :
     C                                       QUSAttr    :
     C                                       vApiErrDs  )
      * Get pointer to user space
     C                   callp     QUSPTRUS(
     C                             uSpaceName:
     C                             uHeadPtr:
     C                             vApiErrDs)
      * call api to load job log into user space.
     C                   callp     QMHLJOBL(
     C                             uSpaceName:
     C                             'LJOB0100':
     C                             MsgSelectDS:
     C                             %len(MsgSelectDS):
     C                             'JSLT0100':
     C                             vApiErrDs)
      * Process elements
      *
     C                   eval      uListPtr  = uHeadPtr + uOffSetToList
 1B  C                   do        uNumOfEntrys

      * Message Type                                              Example
      * 15  Escape, exception already handled when API is called  MCH1211
      * 17  Escape, exception not handled when API is called      CPF9999
      * 06  Sender's copy                                         RNQ0102
      *
      * Example Error: divide by zero
      * Job log sequence : MCH1211 Attempt made to divide by zero
      *                            for fixed point operation.
      *                    CPF9999 Function check. MCH1211
      * unmonitored by TESTERR at statement 0000000007, instruction X'0000'
      *    reply message=> RNQ0102 Attempt to divide by zero (C G D F).

     C                   If        uMsgType = '06' or
     C                             uMsgType = '15' or
     C                             uMsgType = '17'
     C                   eval      uListPtr2 = uHeadPtr + uOffsetToFlds
     C                   If        uMsgType = '15'
     C                   eval      msgtxt15 =
     C                                      %subst(u2Data:1:U2LengthOfData)
     C                   EndIf
     C                   If        uMsgType = '17'
     C                   eval      msgtxt17 =
     C                                      %subst(u2Data:1:U2LengthOfData)
     C                   EndIf
     C                   If        uMsgType = '06'
     C                   eval      msgtxt06 =
     C                                      %subst(u2Data:1:U2LengthOfData)
     C                   EndIf


     C                   EndIf

     C                   eval      uListPtr  = uHeadPtr  + uOffsetToNext
 1E  C                   enddo

     C                   eval      msgtxt = '*** Job MSGW Error Message' +
     C                                      ' *** ' +
     C                                      'Job ' +
     C                                      %trim(jobnumber) + '/' +
     C                                      %trim(jobuser)   + '/' +
     C                                      %trim(jobname)   + ' ' +
     C                                      'error text:'    + ' ' +
     C                                      %trim(msgtxt15) + ' ' +
     C                                      %trim(msgtxt17) + ' ' +
     C                                      %trim(msgtxt06)
     C                   eval      msgtxt494 = msgtxt
     C                   if        %len(%trim(msgtxt15) +
     C                                  %trim(msgtxt17) +
     C                                  %trim(msgtxt06)) > 0
     C                   exsr      SndEzMsg
     C                   EndIf

     C                   return
      **********************************************************************
     C     SndEzMsg      BegSr
     C                   callp     QEZSNDMG( msgTypeA
     C                                     : '*BREAK'
     C                                     : msgtxt494
     C                                     : %len(msgtxt494)
     C                                     : MsgQUsrAry
     C                                     : AryIdx
     C                                     : sentcode
     C                                     : funccode
     C                                     : ErrorCode
     C                                     : 'N'
     C                                     : *blanks
     C                                     : '*USR'
     C                                     : 0 )
     C                   EndSr


File   : QCMDSRC
Member : RTVMSGWJL
Type   : CMD
Usage  : CRTCMD CMD(your-lib/RTVMSGWJL) PGM(your-lib/RTVMSGWJLR)

/*  ===============================================================  */
/*  =  Command....... RtvMsgwJL                                   =  */
/*  =  Source type... CMD                                         =  */
/*  =  Description... Retrieve MSGW Job ErrMsg from Job Log       =  */
/*  =                                                             =  */
/*  =  CPP........... RtvMsgwJLR                                  =  */
/*  =                                                             =  */
/*  ===============================================================  */
/*  = Date  : 2008/03/21                                          =  */
/*  = Author: Vengoal Chang                                       =  */
/*  ===============================================================  */
/*  = Create strp:                                                =  */
/*  =  CRTBNDRPG PGM(RtvMsgwJLR) SRCFILE(LIB/QRPGLESRC)           =  */
/*  =  CRTCMD    CMD(RtvMsgwJL)  PGM(RtvMsgwJLR) +                =  */
/*  =                            SRCFILE(LIB/QCMDSRC)             =  */
/*  ===============================================================  */
      /*------------------------------------------------*/
      /*  Command Definition                            */
      /*------------------------------------------------*/

             CMD        PROMPT('RTV MSGW Job Log and Send')
             PARM       KWD(JOB) TYPE(*SNAME) LEN(10) MIN(1) +
                          PROMPT('Job name')
             PARM       KWD(USER) TYPE(*SNAME) LEN(10) MIN(1) +
                          PROMPT('User name')
             PARM       KWD(JOBNBR) TYPE(*CHAR) LEN(6) RANGE(000000 +
                          999999) MIN(1) PROMPT('Job number')
             PARM       KWD(MSGTYPE) TYPE(*CHAR) LEN(5) RSTD(*YES) +
                          DFT(*INFO) VALUES(*INFO *INQ) +
                          PROMPT('Message type')
             PARM       KWD(TOMSGQ) TYPE(MSGQ) MAX(20) PROMPT('Send +
                          log to message queue')

 MSGQ:       QUAL       TYPE(*NAME) LEN(10) SPCVAL((QSYSOPR)) +
                          EXPR(*YES)
             QUAL       TYPE(*NAME) LEN(10) DFT(*LIBL) +
                          SPCVAL((*LIBL) (*CURLIB)) EXPR(*YES) +
                          PROMPT(Library)





File   : QRPGLESRC
Member : TESTERR
Type   : RPGLE
Usage  : 測試程式 
         此測試程式用於產生除以 0 的錯誤
         CRTBNDRPG TESTERR

D num1            S             10I 0                  
D num2            S             10I 0                  
D result          S             10I 0                  
                                                       
C                   eval      *InLr = *On              
                                                       
C                   eval      result = num1/ num2      
C                                                      

TESTERR 編譯後,執行下列指令:
sbmjob cmd(call testerr) job(testerr)
WRKACTJOB 檢視 JOB TESTERR 執行狀態是 MSGW,記下該 JOB 的 JOB name, Job user, Job number
執行 RTVMSGWJL JOB(jobname) USER(jobuser) JOBNBR(jobnbr) TOMSGQ(anyoneuser)
例如執行 RTVMSGWJL JOB(TESTERR) USER(VENGOAL) JOBNBR(509363) TOMSGQ(VENGOAL)
會收到如下訊息:
>From  . . . :   VENGOAL        05/16/08   11:19:15                  
*** Job MSGW Error Message *** Job 509363/VENGOAL/TESTERR error text
  Attempt made to divide by zero for fixed point operation. Function
  check. MCH1211 unmonitored by TESTERR at statement 0000000007,    
  instruction X'0000'. Attempt to divide by zero (C G D F).                                              

回本期目錄
	




星期二, 11月 07, 2023

2006-12-20 如何擷取某工作 Joblog 中某一 MsgID 的訊息內容是否包含指定字串?(Command SCNJOBLOG)


如何擷取某工作 Joblog 中某一 MsgID 的訊息內容是否包含指定字串?(Command SCNJOBLOG)

File  : QRPGLESRC
Member: SCNJOBMSGR
Type  : RPGLE
Usage : CRTBNDRPG SCNJOBMSGR

     H DFTACTGRP(*NO) ACTGRP(*CALLER) BNDDIR('QC2LE') EXPROPTS(*RESDECPOS)
     H DATFMT(*ISO)   TIMFMT(*ISO)    OPTION(*NODEBUGIO) DEBUG
      *----------------------------------------------------------------
      * SCNJOBLOG  Scan specified job's job log by MSGID to
      * search some string in job log
      * Copyright (C) 12/12/2006  Vengoal Chang    
      * This program is free software, you can redistribute it and/or modify it under the terms
      * of the GNU General Public License as published by the Free Software Foundation.
      *
      *----------------------------------------------------------------
      * This program retrieve specified job job's log and return found
      * search string or not.
      *
      * CRTBNDRPG with target release V5R1 and later
      *
      *----------------------------------------------------------------
      * api (application program interfaces) used:
      * quscrtus  create user space
      * qusptrus  retrieve pointer to user space
      * qmhljobl  list job log messages
      * qmhsndm   send non-program messages
      *----------------------------------------------------------------
     D uSpaceName      s             20    inz('RTVJOBLOG QTEMP     ')
     D msgtxt          s            256
     D QUSLIB          s             10

      *  -------------------------------------------------------------------
      *  -  User space attributes data structure                           -
      *  -------------------------------------------------------------------

     D QUSAttr         DS
     D  QUSNumRec                    10I 0 Inz( 1 )
     D  QUSKey                       10I 0 Inz( 3 )
     D  QUSRecLen                    10I 0 Inz( 1 )
     D  QUSRecData                    1A   Inz( '1' )
      *----------------------------------------------------------------
     D struct          DS
     D  msgdln                       10I 0
     D  msgq#                        10I 0
     D  msgkey                        4
     D  msgq                         20    INZ('QSYSOPR   *LIBL     ')
      *
      *----------------------------------------------------------------
      * Get user space list info from header section.
      *----------------------------------------------------------------
     D                 ds                  based(uHeadPtr)
     D uOffSetToList         125    128i 0
     D uNumOfEntrys          133    136i 0
     D uSizeOfEntry          137    140i 0
      *
     D uListEntry1     ds                  Based(uListPtr )
     D uOffsetToNext                 10i 0 overlay(uListEntry1:1)
     D uOffsetToFlds                 10i 0 overlay(uListEntry1:5)
     D uNumFldsRetrnd                10i 0 overlay(uListEntry1:9)
     D uMsgSeverity                  10i 0 overlay(uListEntry1:12)
     D uMsgId                         7a   overlay(uListEntry1:17)
     D uMsgType                       2a   overlay(uListEntry1:24)
     D uMsgKey                        4a   overlay(uListEntry1:26)
     D uMsgFile                      20a   overlay(uListEntry1:30)
     D uMsgFileName                  10a   overlay(uListEntry1:30)
     D uMsgFileLib                   10a   overlay(uListEntry1:40)
      * these fields repeat for each key selected.
     D uListEntry2     ds                  Based(uListPtr2)
     D u2OffsetToNext                10i 0
     D u2LengthOfFlds                10i 0
     D u2IdentifierF                 10i 0
     D u2TypeOfData                   1a
     D u2StatOfData                   1a
     D u2Reserved                    14a
     D u2LengthOfData                10i 0
     D u2Data                       500
      *----------------------------------------------------------------
      * Error return code parm for APIs.
      *----------------------------------------------------------------
     D vApiErrDs       ds
     D  vbytpv                       10i 0 inz(%size(vApiErrDs))
     D  vbytav                       10i 0 inz(0)
     D  vmsgid                        7a
     D  vresvd                        1a
     D  vrpldta                      50a
      *
      *----------------------------------------------------------------
      * Message selection data structure.
      *
      *                               Retrieve JOB Log direction
      *-----------------------------|-------------|--------------------
      * Parameter                   | From Top    | From Bottom
      *-----------------------------|-------------|--------------------
      * msListDirection             | *NEXT       | *PRV
      * msStartingMessageKey        | X'00000000' | X'FFFFFFFF'
      *----------------------------------------------------------------
     D MsgSelectDS     ds
     D  msMaxMsgRequested...
     D                               10i 0 inz(-1)     overlay(msgSelectDS:1)   num of msg requested
     D  msListDirection...
     D                               10a   inz('*NEXT') overlay(msgSelectDS:5)   List direction
     D  msQualifiedJobName...
     D                               10a   inz('*')    overlay(msgSelectDS:15)     * = current job
     D  msQualifiedUserName...
     D                               10a   inz(' ')    overlay(msgSelectDS:25)       = current job
     D  msQualifiedJobNumber...
     D                                6a   inz(' ')    overlay(msgSelectDS:35)       = current job
     D  msInternalJobIdentifier...
     D                               16a   inz(' ')    overlay(msgSelectDS:41)       = current job
     D  msStartingMessageKey...
     D                                4a   inz(x'00000000')                     start newest message
     D                                                 overlay(msgselectDS:57)
     D  msMaxMsgLength...
     D                               10i 0 inz(500)    overlay(msgSelectDS:61)  id 301,302 lengths
     D  msMaxMsgHelpLength...
     D                               10i 0 inz(100)    overlay(msgSelectDS:65)  id 401,402,403,404
     D  msOffsetToIdentifiersOfFieldstoReturn...
     D                               10i 0 inz(84)     overlay(msgSelectDS:69)  to start of array
     D  msNumberOfFieldsToReturn...
     D                               10i 0 inz(1)      overlay(msgSelectDS:73)
     D  msOffsetToCallMsgQname...
     D                               10i 0 inz(88)     overlay(msgSelectDS:77)
     D  msLengthOfCallMsgQname...
     D                               10i 0 inz(1)      overlay(msgSelectDS:81)
     D  msIndentifiersOfFieldsToReturn...
     D                               10i 0 inz(0302)   overlay(msgSelectDS:85)
     D  msCallMessageQueueName...
     D                                1a   inz('*')    overlay(msgSelectDS:89)
      *----------------------------------------------------------------
      * Create Prototypes for calls
      * --------------------------------------------------------------------
      *  -  QusCrtUs  - Create User Space API                              -
      *  -                                                                 -
      *  -  Usage      Length   Type         Parameter Description         -
      *  -                                                                 -
      *  -  Input          20   Character    Qualified user space name     -
      *  -  Input          10   Character    Extended attribute            -
      *  -  Input         4 0   Binary       Initial size                  -
      *  -  Input           1   Character    Initial value                 -
      *  -  Input          10   Character    Public authority              -
      *  -  Input          50   Character    Text description              -
      * --------------------------------------------------------------------
     D quscrtus        PR                  ExtPgm('QUSCRTUS')
     D                               20
     D                               10    const
     D                               10i 0 const
     D                                1    const
     D                               10    const
     D                               50    const
     D                               10    const
     Db                                    like(vApiErrDS)
      *  -------------------------------------------------------------------
      *  -  Qusptrus      - Get user space pointer       API               -
      *  -                                                                 -
      *  -  Usage      Length   Type         Parameter Description         -
      *  -                                                                 -
      *  -  Input          20   Character    Qualified user space name     -
      *  -  Output          *   Pointer      UserSpace Pointer             -
      *  -  Output                           Error Code                    -
      *  - -----------------------------------------------------------------
     D qusptrus        PR                  ExtPgm('QUSPTRUS')                   retrieve pointer
     D                               20                                         Space Name
     D                                 *                                        pointer
     Db                                    like(vApiErrDS)                      error parm
      *  -------------------------------------------------------------------
      *  -  Quscusat      - Change User Space Attributes API               -
      *  -                                                                 -
      *  -  Usage      Length   Type         Parameter Description         -
      *  -                                                                 -
      *  -  Output         10   Character    Returned library              -
      *  -  Input          20   Character    Qualified user space name     -
      *  -  Input          13   Character    Attribute structure           -
      *  -  Output                           Error code                    -
      *  -------------------------------------------------------------------
     D quscusat        PR                  ExtPgm( 'QUSCUSAT' )
     D                               10A   Const
     D                               20A   Const
     D                               13A   Const
     Db                                    like(vApiErrDS)
      *  ---------------------------------------------------------------
     D system          PR            10I 0 extproc('system')
     D  i_cmd                          *   value options(*string)
      *
     D EXCP_MSGID      S              7A   import('_EXCP_MSGID')
      *  --------------------------------------------------------------
     D qmhljobl        PR                  ExtPgm('QMHLJOBL ')
     D                               20
     D                                8    const
     Db                                    like(MsgSelectDS)
     D                               10i 0 const
     D                                8    const
     Db                                    like(vApiErrDS)
      *  --------------------------------------------------------------
     D SNDPGMMSG       PR                  EXTPGM('QMHSNDPM')
     D   MESSAGEID                    7A   CONST
     D   QUALMSGF                    20A   CONST
     D   MSGDATA                    256A   CONST
     D   MSGDTALEN                   10I 0 CONST
     D   MSGTYPE                     10A   CONST
     D   CALLSTKENT                  10A   CONST
     D   CALLSTKCNT                  10I 0 CONST
     D   MESSAGEKEY                   4A
     D   ERRORCODE                32766A   OPTIONS(*VARSIZE)
      *  --------------------------------------------------------------

     D main            PR                  extpgm('SCNJOBLOGR')
     D  jobname                      10
     D  jobuser                      10
     D  jobnumber                     6
     D  msgId                         7
     D  searchStr                    48
     D  includeQuote                  4
     D  StrFound                      1

     D main            PI
     D  jobname                      10
     D  jobuser                      10
     D  jobnumber                     6
     D  msgId                         7
     D  searchStr                    48
     D  includeQuote                  4
     D  StrFound                      1

     D  searchString   S             50
     D  strpos         S              5I 0
     D  quote          S              1    Inz('''')
     D WWMSGLEN        S             10I 0
     D WWTHEKEY        S              4A
      *----------------------------------------------------------------
     C                   eval      msQualifiedJobName   = jobname
     C                   eval      msQualifiedUserName  = jobuser
     C                   eval      msQualifiedJobNumber = jobnumber
     C                   If        includeQuote = '*YES'
     C                   eval      searchString  = quote + %trim(searchStr) +
     C                                             quote
     C                   Else
     C                   eval      searchString  = %trim(searchStr)
     C                   EndIf
     C                   eval      StrFound = '0'
      *----------------------------------------------------------------
      * Create user space
     C                   callp     QUSCRTUS(
     C                             uSpaceName:
     C                             'TEST':
     C                             1500000:
     C                             x'00':
     C                             '*ALL':
     C                             'User Space RTVJOBLOG' :
     C                             '*NO':
     C                             vApiErrDs)
      * set UserSpace to autoextended
     C                   CallP     QUSCUSAT( QUSLib     :
     C                                       uSpaceName :
     C                                       QUSAttr    :
     C                                       vApiErrDs  )
      * Get pointer to user space
     C                   callp     QUSPTRUS(
     C                             uSpaceName:
     C                             uHeadPtr:
     C                             vApiErrDs)
      * call api to load job log into user space.
     C                   callp     QMHLJOBL(
     C                             uSpaceName:
     C                             'LJOB0100':
     C                             MsgSelectDS:
     C                             %len(MsgSelectDS):
     C                             'JSLT0100':
     C                             vApiErrDs)
      * Process elements
      *
     C                   If        vbytav = 0
     C                   eval      uListPtr  = uHeadPtr + uOffSetToList
 1B  C                   do        uNumOfEntrys

     C                   If        uMsgId = msgId
     C                   eval      uListPtr2 = uHeadPtr + uOffsetToFlds

     C                   eval      msgtxt = %subst(u2Data:1:U2LengthOfData)
     C                   eval      strPos = %scan(%trim(searchString) : msgtxt)
     C                   If        strPos > 0
     C                   eval      StrFound = '1'
     C                   leave
     C                   EndIf

     C                   EndIf

     C                   eval      uListPtr  = uHeadPtr  + uOffsetToNext
 1E  C                   enddo
     C                   Else
     C                   eval      msgtxt = 'API Error: ' + vmsgid +
     C                                 '. Please see job log for detail'
     C                   eval      WWMSGLEN = %len(%trimr(msgtxt))
     C                   CALLP     SNDPGMMSG('CPF9897': 'QCPFMSG   *LIBL':
     C                               msgtxt:WWMSGLEN: '*ESCAPE':
     C                               '*PGMBDY': 1: WWTHEKEY: vApiErrDs)
     C                   EndIf

     C                   eval      *inlr = *on
     C                   return




File  : QCMDSRC
Member: SCNJOBMSG
Type  : CMD
Usage : CRTCMD     CMD(lib/SCNJOBLOG) PGM(lib/SCNJOBLOGR) ALLOW(*IPGM *BPGM)  

/********************************************************************/
/*   Title:      SCNJOBLOG: Scan jobs log                           */
/*                                                                  */
/*   Description - This command performs job log scaned by MSGID    */
/*                                                                  */
/*   The Create Command command should include the following:       */
/*                                                                  */
/*           CRTCMD     CMD(SCNJOBLOG) PGM(SCNJOBLOGR)              */
/*                      ALLOW(*IPGM *BPGM)                          */
/********************************************************************/
/*  =============================================================== */
/*  = Date  : 2006/12/20                                          = */
/*  = Author: Vengoal Chang                                       = */
/*  =============================================================== */
      /*------------------------------------------------*/
      /*  Command Definition                            */
      /*------------------------------------------------*/

             CMD        PROMPT('Scan Job Log by MSGID')
             PARM       KWD(JOB) TYPE(*SNAME) LEN(10) MIN(1) +
                          PROMPT('Job name')
             PARM       KWD(USER) TYPE(*SNAME) LEN(10) MIN(1) +
                          PROMPT('User name')
             PARM       KWD(JOBNBR) TYPE(*CHAR) LEN(6) RANGE(000000 +
                          999999) MIN(1) PROMPT('Job number')
             PARM       KWD(MSGID) TYPE(*CHAR) LEN(7) SPCVAL((*ALL)) +
                          MIN(1) PROMPT('Message ID to be searched')
             PARM       KWD(SCHSTR) TYPE(*CHAR) LEN(50) +
                          PROMPT('String searched in MSGID Text')
             PARM       KWD(QUOTE) TYPE(*CHAR) LEN(4) RSTD(*YES) +
                          DFT(*NO) VALUES(*YES *NO) PROMPT('Include +
                          quote between SCHSTR')
             PARM       KWD(FOUND) TYPE(*CHAR) LEN(1) RTNVAL(*YES) +
                          PROMPT('CL var for String found (1)')


File  : QCLSRC
Member: SCNJOBLOGT
Type  : CLP
Usage : 指定 job, usr, jobnbr, search-msgid, search-string 取代小寫部分
        CRTCLPGM SCNJOBLOGT
        CALL SCNJOBLOGT


PGM
             DCL &RC *CHAR 1 /* RC=1 found, RC <> 1 not found */
             SCNJOBLOG  JOB(job) USER(usr) JOBNBR(jobnbr) +
                          MSGID(search-msgid) SCHSTR(search-string) FOUND(&RC)
             MONMSG CPF9897
ENDPGM




星期一, 11月 06, 2023

2004-11-20 如何將訊息紀錄於 JobLog ? (API Qp0zLprintf(Print Formatted Job Log Data))


如何將訊息紀錄於 JobLog ? (API Qp0zLprintf(Print Formatted Job Log Data))

將訊息紀錄於 JobLog 有幾種方式, 可以呼叫 CL 指令 SNDPGMMSG 或 API QMHSNDPM ,
但是有一 API Qp0zLprintf (Print Formatted Job Log Data) 更容易使用, 其參數
使用方式如同 C 函式 printf, 但必須於字串尾端加上 X'25' 表示訊息結尾. 


File  : QRPGLESRC
Member: WRTJOBLOGR
Type  : RPGLE
Usage : CRTBNDRPG WRTJOBLOGR
      : CALL WRTJOBLOGR


     H DEBUG  OPTION(*SRCSTMT:*NODEBUGIO) DFTACTGRP(*NO) ACTGRP(*CALLER)

     D Qp0zLprintf     PR            10I 0 ExtProc('Qp0zLprintf')
     D  szOutputStg                    *   Value OPTIONS(*STRING)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)
     D                                 *   Value OPTIONS(*STRING:*NOPASS)

     D ProdNo          S              5  0 Inz(1234)
     D ProdName        S             30    Inz('Testing')

     C                   Callp     Qp0zLprintf('Hello OS/400'+X'25')

     C                   callp     Qp0zLprintf('ProdNo: %s %s' + X'25' :
     C                                %char(ProdNo):%Trimr(ProdName))

     C                   Eval      *InLr = *On

執行 CALL WRTJOBLOGR 後, DSPJOBLOG 會有如下訊息:

     Hello OS/400        
     ProdNo: 1234 Testing

此 API 非常方便於除錯或紀錄程式執行狀態.





2004-10-18 如何於 RPG 中將程式執行中的訊息寫入 JobLog 中 ?(API QMHSNDPM)


如何於 RPG 中將程式執行中的訊息寫入 JobLog 中 ?(API QMHSNDPM)

File  : QRPGLESRC
Member: SNDPGMMSGR
Type  : RPGLE
Usage : CRTBNDRPG SNDPGMMSGR
        CALL SNDPGMMSGR
        畫面 24 行會顯示此程式所傳送之訊息,同時此訊息亦會寫入JOBLOG,可以執行
        DSPJOBLOG 顯示 Job Log(工作日誌)。
        此範例中有四種訊息傳送方式,最常使用是 *INFO(一般資訊), *COMP(程式執行完成時的訊息), 
        *DIAG(程式錯誤偵測訊息), *ESCAPE(程式執行錯誤訊息),一般當系統偵測到程式執行錯誤時,
        會先發送 *DIAG 訊息,再發送 *ESCAPE 訊息,但是如果是自己所寫的程式可以直接發送
        *ESCAPE 訊息,通知系統程式不正常結束。


     H dftactgrp(*NO)

     D sndpgmmsg       PR
     D   peMsg                      256A   const
     D   outMsgType                  10A   const


     C                   callp     sndpgmmsg('test  *INFO' : '*INFO')
     C                   callp     sndpgmmsg('test  *COMP' : '*COMP')
     C                   callp     sndpgmmsg('test  *DIAG' : '*DIAG')
     C                   callp     sndpgmmsg('test  *ESCAPE msg' : '*ESCAPE')

     C                   eval      *InLr = *On

      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      *  This ends this program abnormally, and sends back an escape.
      *   message explaining the failure.
      *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
     P sndpgmmsg       B
     D sndpgmmsg       PI
     D   peMsg                      256A   const
     D   outMsgType                  10A   const

     D QMHSNDPM        PR                  ExtPgm('QMHSNDPM')
     D   MessageID                    7A   Const
     D   QualMsgF                    20A   Const
     D   MsgData                    256A   Const
     D   MsgDtaLen                   10I 0 Const
     D   MsgType                     10A   Const
     D   CallStkEnt                  10A   Const
     D   CallStkCnt                  10I 0 Const
     D   MessageKey                   4A
     D   ErrorCode                32766A   options(*varsize)

     D dsEC            DS
     D  dsECBytesP             1      4I 0 INZ(256)
     D  dsECBytesA             5      8I 0 INZ(0)
     D  dsECMsgID              9     15
     D  dsECReserv            16     16
     D  dsECMsgDta            17    256

     D wwMsgLen        S             10I 0
     D wwTheKey        S              4A

     c                   eval      wwMsgLen = %len(%trimr(peMsg))
     c                   if        wwMsgLen<1
     c                   return
     c                   endif

     c                   callp     QMHSNDPM('CPF9897': 'QCPFMSG   *LIBL':
     c                               peMsg: wwMsgLen: %trim(outMsgType):
     c                               '*PGMBDY': 1: wwTheKey: dsEC)
     c*                  callp     QMHSNDPM('CPF9897': 'QCPFMSG   *LIBL':
     c*                              peMsg: wwMsgLen: %trim(outMsgType):
     c*                              '*': 3: wwTheKey: dsEC)

     c                   return
     P                 E

            




星期四, 11月 02, 2023

Best Practices for Managing Job Logs on IBM i

 https://www.redbooks.ibm.com/abstracts/tips0679.html?Open

For our discussion, we focus on why are job logs kept and whether you can use a more granular control.

First, you can set up a job’s logging level to get all messages logged to the job log, but the job log is produced only if the job ends abnormally. If the job ends normally, no job log is generated, using the LOG(4 0 *NOLIST) setting.

When ending jobs, you can indicate that you do not want a job log, as shown in the following table.

CommandParameter for no job log
End Job (ENDJOB)LOGLMT(0)
End Prestart Jobs (ENDPJ)LOGLMT(0)
End Group Job (ENDGRPJOB)LOG(*NOLIST)
End Subsystem (ENDSBS)ENDSBSOPT(*NOJOBLOG)
End System (ENDSYS)ENDSBSOPT(*NOJOBLOG)
Power Down System (PWRDWNSYS)ENDSBSOPT(*NOJOBLOG)
Clear Job Queue (CLRJOBQ)LOG(*NONE)
Sign Off (SIGNOFF)LOG(*NOLIST)

Consider the following system values with associated job attributes for job log characteristics:

  • QJOBMSGQFL: Job message queue full action

    This system value determines the behavior when the job message queue is full.

    *NOWRAP ends the job when the job message queue is full. Use this value to prevent short running jobs from looping endlessly in error situations.

    *WRAP allows new messages to overlay old messages when the job message queue is full. Use this value for long running jobs.

    *PRTWRAP creates a spooled file for the job log prior to wrapping to allow new messages to overlay old messages.

  • QJOBMSGQMX: Maximum size of job message queue

    This system value sets the size of a job’s message queue. The shipped value is 16 MB, which for many jobs might be too high. Setting this system value to a high number can over commit a system’s storage. For example, if you have 20 000 active jobs and set QJOBMSGQMX to 64, the system can (in the worst case) use 1 280 000 megabytes for job message queues. Even systems that are large enough to run a lot of active jobs probably do not have that much unused DASD. When jobs hit a common error loop, even if it is only 5% of the active jobs, you can start losing storage quickly. Two points:

    You need to set limits using the system value and the job description values.

    The system uses storage to run. It uses a lot more storage to handle errors, and you need a fairly wide margin to avoid running out of storage.

    Setting QJOBMSGQMX to 8 and QJOBMSGQFL set to *WRAP is a good, general configuration. If you have a specific need for a larger job log, set these values with care and with knowledge about the jobs that specifically need that high of a job log for special problem cases. Setting the QJOBMSGQMX system value to 8 limits the number of job log messages for a job. It can also reduce the recovery time for IPL after some system failures.

  • QLOGOUTPUT: Job log output

    This system value allows you to control if, and when, spooled job logs are created.

    *JOBEND specifies that job logs are spooled when the job ends. Only use *JOBEND if you have a dependency on the job log being available immediately after the job ends. When many jobs end at the same time, using *JOBEND can result in a CPU spike as well as potential contention on the output queue.

    *JOBLOGSVR specifies that job logs are spooled by the Job Log Servers some time after the job ends. Using *JOBLOGSVR is fairly close to using *JOBEND and tends to operate more smoothly (with less contention and less CPU spike).

    You might want to shut down the job log servers to a restricted state before ending the jobs, depending on how much sequencing you do when ending work. Ending the job log servers prior to going into restricted state prevents the writing of job logs for jobs that are being ended (assuming those jobs use *JOBLOGSVR). IBM generally recommends using *JOBLOGSVR.

    *PND keeps the job logs in a pending state until they are spooled or deleted from the system. Pending job logs reduce CPU and contention. Pending job logs, however, consume a job structure, even if you are detaching spooled files. The job descriptions for several server jobs are configured to use LOGOUTPUT(*PND), helping to avoid CPU spikes and contention when large number of server jobs end at the same time. The automatic cleanup function (GO CLEANUP) deletes pending job logs in the same manner as spooled job logs; however, if you are not using the system’s cleanup feature, then you must do your own cleanup. Cleanup is not optional, because if cleanup is not done, the system can run out of job structures or can fill with spooled files. To clean up pending job logs, use the QWTRMVJL API:


    Specify a zero value for the “days since job completion” parameter to clean up the job logs immediately. Finally, if you are using the QMHCTLJL API, do not use pending job logs. Using the control job log output API makes sense only if you are creating the job log when the job ends.

    V5R4 introduced the WRKJOBLOG command. You can delete job logs from this interface. In V6R1, you have the option to delete all job logs.

  • QJOBMSGQSZ: Job message queue initial size

    This system value is obsolete and no longer used.

  • QJOBMSGQTL: Job message queue maximum initial size.

    This system value is obsolete and no longer used.


For a more detailed discussion about this topic, refer to Best Practices for Managing IBM i Jobs and Output (and a few other special tips), REDP-4454.