× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



"MIDRANGE-L" <midrange-l-bounces@xxxxxxxxxxxx> wrote on 06/19/2017
06:10:48 PM:
I didn't miss the point. Thanks to Brian for sharing it.

The reason I don't consider this a "correction" to what you were
saying is that, for my purposes, it's just too far down the rabbit
hole and off the beaten path.

Understood. If you're interested, I have a service procedure that
can be called from CLLE to retrieve up to the last 10 messages from the
current joblog. It is not fully encapsulated, though, so where it calls
other service routines you would have to supply your own code to obtain an
encapsulated version of this. It also utilizes definitions from
IBM-supplied RPG copybooks in the QSYSINC library.

It returns message type, message id, message file, msgfile
library, and message replacement data for each of those up to 10 messages
in an array that can be looped through in CLLE to make it easy to examine
DIAG messages in reverse order. I currently use it as part of my standard
batch error handling routine which sends a diagnostic email expanding the
failing message and attaching the last 10 joblog messages for ease of
diagnosis -- potentially avoiding having to either examine printed joblogs
or try and reproduce the error in interactive debug.

This is the service procedure part:

// data structure to return message information
dcl-ds GenUtl_MsgInfo dim(20) qualified;
Id char(7);
Type char(10);
File char(10);
FLib char(10);
Data varchar(3000);
end-ds;

//========================================================================
// get information about the last nnnnn messages in the current joblog
//========================================================================
dcl-proc GenUtl_GetLastJoblogMessages export;
dcl-pi *n;
pMsgCnt packed(5:0);
pMsgInfo likeds(GenUtl_MsgInfo)
dim(%elem(GenUtl_MsgInfo))
options(*varsize);
end-pi;

dcl-s iMsgCnt like(pMsgCnt);
dcl-s curmsg like(pMsgCnt);
dcl-s idx like(pMsgCnt);
dcl-s ofs int(10:0);
dcl-s ofs2 like(ofs);
dcl-s msgtyp char(10);
dcl-s ListRcvr char(32767);

dcl-ds selinfo qualified;
MSI likeds(QGYOMSI);
QGYFID int(10:0) dim(1);
QGYCMQN char(10);
end-ds;

iMsgCnt = pMsgCnt; // number of messages requested
if iMsgCnt < 1; // if last *EXCP message requested
iMsgCnt = 1; // default to 1 message
endif;

clear selinfo; // clear selection information ds
selinfo.MSI.QGYLD = '*PRV'; // get most recent messages first
selinfo.MSI.QGYJN = '*'; // from this job's joblog
selinfo.MSI.QGYSMK = *hival; // starting at end of joblog
selinfo.MSI.QGYIDO = %len(selinfo.MSI); // offset to selection criteria
selinfo.MSI.QGYNBRF00 = 1; // number of field id's
selinfo.MSI.QGYQO = selinfo.MSI.QGYIDO
+ %size(selinfo.QGYFID:*ALL); // offset to msg que
name
selinfo.MSI.QGYMQNS = %len(selinfo.QGYCMQN); // length of msg queue name
selinfo.QGYFID(1) = 0201; // replacement data or impromptu msg
text
selinfo.QGYCMQN = '*'; // call stack message queue name

callp IBMAPI_ListJobLogMessages( ListRcvr: %len(ListRcvr): QGYOLI
: 1: selinfo: %len(selinfo): ApiErrC);
if ApiErrC.BytAvail > *zero; // if API error, report it
callp GenUtl_Escape(ApiErrC.MsgId: ApiErrC.MsgData: 'QCPFMSG');
endif;

curmsg = 1; // set message counter
idx = *zero; // set message index

dow idx < iMsgCnt // load requested number of messages
and ApiErrC.MsgId <> 'GUI0006'; // unless end of message list exceeded

QGYORV = %subst(ListRcvr: 1: %len(QGYORV)); // map message header
ofs = QGYOTFR + 1; // set offset to field identifier (FID)
QGYOIDFI = %subst(ListRcvr: ofs: %len(QGYOIDFI)); // map FID header
ofs2 = ofs + %len(QGYOIDFI); // set offset to data associated w/ FID

select; // interpret message type
when QGYMT = '01'; // completion
msgtyp = '*COMP';
when QGYMT = '02'; // diagnostic
msgtyp = '*DIAG';
when QGYMT = '04'; // informational
msgtyp = '*INFO';
when QGYMT = '05'; // inquiry
msgtyp = '*INQ';
when QGYMT = '06'; // sender's copy
msgtyp = '*COPY';
when QGYMT = '08'; // request
msgtyp = '*RQS';
when QGYMT = '10'; // request with prompting
msgtyp = '*RQS';
when QGYMT = '14'; // notify, exception already handled
msgtyp = '*NOTIFY';
when QGYMT = '15'; // escape, exception already handled
msgtyp = '*ESCAPE';
when QGYMT = '16'; // notify, exception not yet handled
msgtyp = '*NOTIFY';
when QGYMT = '17'; // escape, exception not yet handled
msgtyp = '*ESCAPE';
other; // unknown
msgtyp = '*MT' + QGYMT;
endsl;

if pMsgCnt > *zero // if all msg types requested
or pMsgCnt = *zero // or only exception messages
and msgtyp = '*ESCAPE'; // and this is an exception msg
idx += 1; // then increment message index
pMsgInfo(idx).Id = QGYMID; // and load message id
pMsgInfo(idx).Type = msgtyp; // message type
pMsgInfo(idx).File = QGYMFILN; // message file name
pMsgInfo(idx).FLib = QGYML; // message file library name
pMsgInfo(idx).Data = %trimr(%subst(ListRcvr: ofs2: QGYDL)); // repl.
data
endif;

if idx < iMsgCnt; // max requested not exceeded?
curmsg += 1; // increment message counter
callp IBMAPI_GetListEntry( ListRcvr: %len(ListRcvr): QGYRH00
: QGYOLI: 1: curmsg: ApiErrC); // get prev.
msg
if ApiErrC.BytAvail > *zero // if API error, report it
and ApiErrC.MsgId <> 'GUI0006'; // unless it is end of list
callp GenUtl_Escape(ApiErrC.MsgId: ApiErrC.MsgData: 'QCPFMSG');
endif;
endif;

enddo; // loop on message count

callp IBMAPI_CloseList(QGYRH00: ApiErrC); // close the list
if ApiErrC.BytAvail > *zero; // if API error, report it
callp GenUtl_Escape(ApiErrC.MsgId: ApiErrC.MsgData: 'QCPFMSG');
endif;

pMsgCnt = idx; // pass back number of messages
retrieved
return; // return to caller
end-proc;

...and to call from CL:

/******************************************************************************/
/* Data Structure for JobLog Message Info (See GenUtl_MsgInfo in UT010SV)
*/
/*----------------------------------------------------------------------------*/
/* &MSG_INFID is the message id from the message file indicated below;
*/
/* &MSG_INFTPE is the type (*DIAG, *ESCAPE, etc.) for the indicated
message; */
/* &MSG_INFFLE is the message file for the indicated message id; */
/* &MSG_INFFLB is the library for the indicated message file; */
/* &MSG_INFDLN is the length of the following substitution data; and, */
/* &MSG_INFDTA is the substitution data for the indicated message id. */
/******************************************************************************/
DCL VAR(&MSGINFO) TYPE(*CHAR) LEN(30390) /* array with 10 elements */
DCL VAR(&MSGINFP) TYPE(*PTR) ADDRESS(&MSGINFO)
DCL VAR(&MSGINFE) TYPE(*CHAR) STG(*BASED) LEN(3039) BASPTR(&MSGINFP)
DCL VAR(&MSG_INFID) TYPE(*CHAR) LEN(7) STG(*DEFINED) DEFVAR(&MSGINFE
1)
DCL VAR(&MSG_INFTPE) TYPE(*CHAR) LEN(10) STG(*DEFINED) DEFVAR(&MSGINFE
8)
DCL VAR(&MSG_INFFLE) TYPE(*CHAR) LEN(10) STG(*DEFINED) DEFVAR(&MSGINFE
18)
DCL VAR(&MSG_INFFLB) TYPE(*CHAR) LEN(10) STG(*DEFINED) DEFVAR(&MSGINFE
28)
DCL VAR(&MSG_INFDLN) TYPE(*UINT) LEN(2) STG(*DEFINED) DEFVAR(&MSGINFE
38)
DCL VAR(&MSG_INFDTA) TYPE(*CHAR) LEN(3000) STG(*DEFINED)
DEFVAR(&MSGINFE 40)

DCL VAR(&SQ) TYPE(*DEC) LEN(2 0)
DCL VAR(&MSGIDX) TYPE(*INT) LEN(2)
DCL VAR(&MSGMAX) TYPE(*INT) LEN(2)

/* ============================================================= */
/* ============= R E T R I E V E J O B L O G ============= */
/* ============================================================= */
CHGVAR VAR(&MSGCNT) VALUE(10)
CALLPRC PRC(GENUTL_GETLASTJOBLOGMESSAGES) +
PARM((&MSGCNT) (&MSGINFO))

/* loop through joblog and append to email text */
CHGVAR VAR(&TXTBODY) VALUE(&TXTBODY *TCAT +
'<br><br><br>Joblog messages :')
CHGVAR VAR(&MSGMAX) VALUE(&MSGCNT)

DOFOR VAR(&MSGIDX) FROM(1) TO(&MSGMAX) BY(+1)
IF COND(&MSG_INFID *GT ' ') THEN(DO)
IF COND(&MSG_INFDLN *LT 1) THEN(DO)
CHGVAR VAR(&MSG_INFDLN) VALUE(1)
ENDDO
CHGVAR VAR(&ERRMDATA) VALUE(%SST(&MSG_INFDTA +
1 &MSG_INFDLN))
CALL PGM(UTMMERGR) PARM(&MSG_INFID &MSG_INFFLE +
&MSG_INFFLB &ERRMDATA &ERRMTEXT &DTALEN)
SELECT
WHEN COND(&DTALEN *LT 1) THEN(DO)
CHGVAR VAR(&DTALEN) VALUE(1)
ENDDO
WHEN COND(&DTALEN *GT 90) THEN(DO)
CHGVAR VAR(&DTALEN) VALUE(90)
ENDDO
ENDSELECT
CHGVAR VAR(&TXTBODY) VALUE(&TXTBODY *TCAT +
'<br>' *CAT '-' *CAT %CHAR(&SQ) +
*BCAT %SST(&MSG_INFTPE 1 5) +
*CAT ' ' *CAT &MSG_INFID *CAT ' ' +
*CAT %SST(&ERRMTEXT 1 &DTALEN))
ENDDO
CHGVAR VAR(&SQ) VALUE(&SQ + 1)
CHGVAR VAR(%OFS(&MSGINFP)) VALUE(%OFS(&MSGINFP) +
+ %LEN(&MSGINFE))
ENDDO

Sincerely,

Dave Clark

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.