retreiving Job information (command String) for jobs waiting in job queues on an Iseires

135 pts.
Tags:
iSeries
iSeries programming commands
When we submit a job on an Iseries to a job queue, it gets submitted with a command string. I have a process where I am using APIs to go out and get information on jobs that are on our job queues that are waiting to run. The APIs that I use work great but they do not show me the command string that is associated to a job. After I get the job info I have to do a DSPJOB JOB(&NUMBER/&USER/&JOBNAME) OUTPUT(*PRINT) + OPTION(*JOBLOG) Then I copy it to a spool file and read that file for the command string info. This is time consuming because we get thousands of jobs submitted. Does any one know of a better and or quicker way of doing this? I looked in the Retrieve Call Stack (QWVRCSTK) API but it does not give me the detail the I need. Any help at all is very much appreciated.
ASKED: September 1, 2009  7:11 PM
UPDATED: May 14, 2010  2:48 AM

Answer Wiki

Thanks. We'll let you know when a new response is added.

Rather than dumping the joblog to an output queue have you considered replacing that logic with calling either the <a href=”http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/apis/QMHLJOBL.htm”>List Job Log Messages (QMHLJOBL) API</a> or the <a href=”http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/apis/QGYOLJBL.htm”>Open List of Job Log Messages (QGYOLJBL) API</a>? I haven’t had a chance to test either for your situation but they should do the trick.

Another approach, and one that I have used in the past but which would mean more change to your current process, is be to use the <a href=”http://publib.boulder.ibm.com/infocenter/iseries/v5r4/topic/apis/xcartv.htm”>Command Analyzer Retrieve Exit Program</a> exit point. You could register your exit program with the SBMJOB command and simply be passed the relevant data (in keyword format) as a parameter.

Any of the above would certainly be more direct (and even supported!) than going through a spool file.

There are probably some other ways to accomplish your task, but those are the ones that come to mind.

Bruce Vining
<a href=”http://www.brucevining.com/”>Bruce Vining Services</a>

—————————————————————-

Thanks for your input. I will try these.

===========================================

I ran across this question today and also ran across a test program I had from a few years ago that mostly does this exact thing:<pre>
pgm ( +
&pqjob +
)

dcl &pqjob *char 26

/* */
/* *Usrspc variables… */
/* */
dcl &usrspc *char 20 /* Space name/lib */

dcl &offslst *int /* Offset to list */ +
value( 1 )
dcl &sizlste *int /* Size list entries */ +
value( 150 )
dcl &nbrlste *dec ( 7 0 ) /* Number of entries */

dcl &us_hdr *char 150 /* Space header */

dcl &us_jobe *char 1024 /* A single entry */

dcl &us_rtnfld *char 512 /* Msg returned flds */

/* */
/* Log selection variables… */
/* */
dcl &jslt0100 *char 256 /* Formatted… */

dcl &rtnmaxmsg *char 4 value( x’000000FF’ )
dcl &rtnlstdir *char 10 value( ‘*PRV ‘ )
dcl &rtnintjob *char 16 value( ‘ ‘ )
dcl &rtnstrkey *char 4 value( x’FFFFFFFF’ )
dcl &rtnmaxmlen *char 4 value( x’00000050′ )
dcl &rtnmaxmhlp *char 4 value( x’00000050′ )
dcl &rtnoffsid *char 4 value( x’00000054′ )
dcl &rtnnbrfld *char 4 value( x’00000001′ )
dcl &rtnoffscmq *char 4 value( x’00000058′ )
dcl &rtnlencmq *char 4 value( x’00000004′ )

dcl &szMsgSlt *int value( 256 )
dcl &lRqsMsg *int

/* Variable keys to select */
dcl &rtvmsgtxt *char 4 value( x’0000012D’ )
/* bin( 301 ) */
/* */
/* Retrieved values from job list… */
/* */
dcl &job *char 10
dcl &user *char 10
dcl &nbr *char 6

dcl &curuser *char 10 /* Current user */

dcl &RqsMsg *char 512 /* Request message */

dcl &offnxtmsg *int /* Offset to nxtmsg */
dcl &offrtnfld *int /* Offset to rtnfld */
dcl &msgtyp *char 2 /* Message type */

dcl &offsdta *dec ( 7 0 ) /* Message type */

/* */
/* Global message monitor… */
/* */

monmsg ( cpf0000 mch0000 ) exec( goto Std_Err )

chgvar &job %sst( &pqjob 1 10 )
chgvar &user %sst( &pqjob 11 10 )
chgvar &nbr %sst( &pqjob 21 6 )

chgvar &curuser ‘*N/A’

/* */
/* Create a *usrspc to work with… */
/* */

chgvar &usrspc ( ‘JOBLOG ‘ *cat ‘QTEMP ‘ )

call QUSCRTUS ( +
&usrspc +
‘TMPLST ‘ +
x’00001000′ +
X’00′ +
‘*ALL ‘ +
‘Temp list joblog ‘ +
‘*YES ‘ +
x’0000000000000000′ +
)

/* */
/* This sets up selection criteria for list jobs API… */
/* */

/* The joblog messages we’re after… */

chgvar &jslt0100 ( &rtnmaxmsg *cat +
&rtnlstdir *cat +
&pqjob *cat +
&rtnintjob *cat +
&rtnstrkey *cat +
&rtnmaxmlen *cat +
&rtnmaxmhlp *cat +
&rtnoffsid *cat +
&rtnnbrfld *cat +
&rtnoffscmq *cat +
&rtnlencmq *cat +
&rtvmsgtxt *cat +
‘*EXT’ +
)

/* */
/* This lists joblog msgs for this job… */
/* */

call QMHLJOBL ( +
&usrspc +
‘LJOB0100′ +
&jslt0100 +
&szMsgSlt +
‘JSLT0100′ +
x’0000000000000000′ +
)

/* */
/* Get the *usrspc header for the list attributes… */
/* */

call QUSRTVUS ( +
&usrspc +
&offslst +
&sizlste +
&us_hdr +
)

/* */
/* Get the offset to the list within the space, the number */
/* of list entries and size of each entry from the header. */
/* */
chgvar &offslst %bin( &us_hdr 125 4 )
chgvar &nbrlste %bin( &us_hdr 133 4 )

/* If no entries, then get out of here… */

if ( &nbrlste *eq 0 ) do
sndpgmmsg msgid( CPF9898 ) msgf( QCPFMSG ) +
msgdta( ‘No active jobs found.’ )
goto Clean_up
enddo

/* Set the offset to the list within the space… */

chgvar &offslst ( &offslst + 1 )

chgvar &sizlste ( 1024 ) /* The entry size… */

Nxt_JobE:

/* Get an entry from the list… */

call QUSRTVUS ( +
&usrspc +
&offslst +
&sizlste +
&us_jobe +
)

/* Extract job info from list entry… */

chgvar &offnxtmsg %bin( &us_jobe 1 4 )
chgvar &offrtnfld %bin( &us_jobe 5 4 )
chgvar &msgtyp %sst( &us_jobe 24 2 )

/* If it’s a *RQS msg… */

if ( &msgtyp *eq ’08′ ) do

/* Get the data from the list… */

chgvar &offslst ( &offrtnfld + 1 )
call QUSRTVUS ( +
&usrspc +
&offslst +
x’00000200′ +
&us_rtnfld +
)

/* Extract msg info from list entry… */

chgvar &lRqsMsg %bin( &us_rtnfld 29 4 )
chgvar &RqsMsg %sst( &us_rtnfld 33 &lRqsMsg )
sndpgmmsg msgid( CPF9898 ) msgf( QCPFMSG ) +
msgdta( ‘Job<’ *cat &nbr *tcat +
‘/’ *cat &user *tcat +
‘/’ *cat &job *tcat +
‘> Request msg<’ *cat &RqsMsg *tcat +
‘>’) +
msgtype( *DIAG )
enddo

/* Perform loop testing… */

chgvar &nbrlste ( &nbrlste – 1 )

if ( &nbrlste *gt 0 ) do

chgvar &offslst ( &offnxtmsg + 1 )
goto Nxt_JobE

enddo

/* */
/* Exit processing… */
/* */

Clean_up:

dmpclpgm
dmpobj %sst( &usrspc 11 10 )/%sst( &usrspc 1 10 ) objtype(*usrspc)
dltusrspc %sst( &usrspc 11 10 )/%sst( &usrspc 1 10 )

return

Std_Err:

/* Move any *DIAG messages up the stack… */

Qsys/call pgm( QSYS/QMHMOVPM ) parm( +
‘ ‘ +
‘*DIAG ‘ +
x’00000001′ +
‘* ‘ +
x’00000001′ +
x’00000000′ +
)
Qsys/monmsg ( CPF0000 MCH0000 )

/* Resend any *ESCAPE messages up the stack… */

Qsys/call pgm( QSYS/QMHRSNEM ) parm( +
‘ ‘ +
x’00000000′ +
)
Qsys/monmsg ( CPF0000 MCH0000 )

return

endpgm</pre>
It <b>is not</b> perfect. It assumes that the request messages will never be long than 256-bytes for example. I didn’t when I wrote it; I just wanted to see how it could be done. THIS IS ONLY A TEST.

Regardless, it accepts a fully-qualified job name in {jobname jobuser number} format and returns/displays all *RQS (request) messages that it finds in the joblog. It does work. If a job is on a job queue, there should never be more than one *RQS message. If you use it on an active job, e.g., your interactive job, it should be capable if grabbing all *RQS messages up to the point that it ran.

You can use it to guide creating your own version. Ask questions if something doesn’t make sense or if problems come up.

Tom

Discuss This Question: 1  Reply

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
  • Yorkshireman
    I'd go the simple route, and have each submitter write its command string to a file, which you could then use to generate some metrics, and even update at end of job with CPU seconds used etc..
    5,520 pointsBadges:
    report

Forgot Password

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

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Thanks! We'll email you when relevant content is added and updated.

Following