Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.
Here is what I want to do, I want to be able to run (batch) a wrkusrjob
WRKUSRJOB USER(*ALL) STATUS(*ACTIVE) JOBTYPE(*INTERACT)
but capture the spooled output into a physical file so that I can go and then read through it.
Or maybe there is a better way. Basically what I want to do is that I want to make sure that at 11:45 p.m that there is only x number of jobs showing (any more or less) means that there is an issue and backup won't run (or be right) (as folks are on). And if there isn't then it will send an alarm to me (text or whatever).
I read a bit with the wrkusrjob that ovrprtf does not work with it, etc. maybe I misunderstood.
Or is there some other way to retrieve active interactive job listing?
Recall primarily running in S/36E mode but have various other stuff running. I also have php on the box so if retrieval is easy with php, that too would be an option.
O
This is what we use before we put our system into restricted state for a SavSys
File Layout
A R DPSYSRS TEXT('QINTER & QBATCH ')
A RSFL1 6 TEXT('BLANK')
A COLHDG('BLANK')
A RSSBS 10 TEXT('SUBSYSTEM')
A COLHDG('SUBSYSTEM')
A RSFL2 27 TEXT('BLANK')
A COLHDG('BLANK')
A RSSBA 7 TEXT('JOBS ACTIVE')
A COLHDG('JOBS ACTIVE')
A RSFL3 82 TEXT('BLANK')
A COLHDG('BLANK')
CLLE Program List
PGM
DCL VAR(&CNTBA) TYPE(*CHAR) LEN(7) VALUE('*ZERO')
DCL VAR(&CNTIA) TYPE(*CHAR) LEN(7) VALUE('*ZERO')
DCL VAR(&JOBNME) TYPE(*CHAR) LEN(10)
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(10)
DCLF FILE(DPPSYSRS)
RTVJOBA JOB(&JOBNME) USER(&USER) NBR(&JOBNBR)
CLRPFM FILE(DPPSYSRS)
/**************************************************/
OVRPRTF FILE(QPDSPSBS) HOLD(*YES)
WRKSBS OUTPUT(*PRINT)
CPYSPLF FILE(QPDSPSBS) TOFILE(DPPSYSRS) +
JOB(&JOBNBR/&USER/&JOBNME) SPLNBR(*LAST)
MONMSG MSGID(CPF3303 CPF3311 CPF3429)
DLTSPLF FILE(QPDSPSBS) JOB(&JOBNBR/&USER/&JOBNME) +
SPLNBR(*LAST)
MONMSG MSGID(CPF0000)
READ: RCVF RCDFMT(DPSYSRS)
MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(END ))
IF COND(&RSSBS *EQ 'QBATCH') THEN(DO)
IF COND(&RSSBA *NE '0') THEN(CHGVAR VAR(&CNTBA) +
VALUE(&RSSBA))
GOTO READ
ENDDO
IF COND(&RSSBS *EQ 'QINTER') THEN(DO)
IF COND(&RSSBA *NE '0') THEN(CHGVAR VAR(&CNTIA) +
VALUE(&RSSBA))
GOTO READ
ENDDO
GOTO READ
END:
SNDMSG MSG('There are still ' |> &CNTIA |< ' users +
signed on and ' |> &CNTBA |< ' batch jobs +
running that have to be cancelled before +
terminating to a restricted state.') +
TOMSGQ(QSYSOPR)
/* you could email or text out at this point */
ENDPGM
You can use the List Job API: QUSLJOB to do this. Running an API is generally faster way of doing things like this than running a command to produce a spool file, then reading the spool file.
Forget about the performance aspect. API's are upwards compatible with new releases. Format of a spooled file can change at any new release, possibly by PTF, meaning you'd have to review and possibly modify your program all the time.
But, just curious, are you not using save-while-active? The only thing I ever remember having problems with was a lock that prevented a *DTAQ from being saved. Never had troubles with open *FILE's, and, of course, there are no locks on active *PGM's.
(I eventually ended the QRCVDTAQ job right before the save, and restarted after giving a few minutes for the save-while-active checkpoint to be reached. Another option, in this case, would have been to omit the object, since there were no recovery issues.)
the reason I don't do save while active is a want a snapshot that is 100% "pure", not with some parts partially changed. However, thinking about it, maybe that is what I need to do and not worry about it.
I took at look at save while active on the savlib command and there are *NO, *SYNCLIB, *LIB and *SYSDFN and I read the text and I guess that *SYSDFN would be o.k. but if someone has a file open and in an update mode (which would be a record lock situation) is the SAVLIB going to sit? (if so then "save while active" doesn't help me.
To see how many jobs are active in a certain subsystem you could use the Retrieve Subsystem API (QWDRSBSD). See supplied code for an example.
Regards,
Carel Teijgeler
PGM PARM(&QSBS &RTNLIB &STATUS &ACTJOB)
INPUT: DCL VAR(&QSBS) TYPE(*CHAR) LEN(20)
DCL VAR(&RTNLIB) TYPE(*CHAR) LEN(10)
DCL VAR(&STATUS) TYPE(*CHAR) LEN(10)
DCL VAR(&ACTJOB) TYPE(*DEC) LEN(5 0)
JOB: DCL VAR(&RTNVAR) TYPE(*CHAR) LEN(360)
DCL VAR(&RTNLEN) TYPE(*CHAR) LEN(4)
DCL VAR(&DTAFMT) TYPE(*CHAR) LEN(8) +
VALUE('SBSI0100')
DCL VAR(&APIERR) TYPE(*CHAR) LEN(4) +
VALUE(X'00000000')
FOUTJE: DCL VAR(&KEYVAR) TYPE(*CHAR) LEN(4)
DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(200)
DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
CHGVAR VAR(%BIN(&RTNLEN)) VALUE(360)
CALL PGM(QWDRSBSD) PARM(&RTNVAR &RTNLEN &DTAFMT +
&QSBS &APIERR)
CHGVAR VAR(&RTNLIB) VALUE(%SST(&RTNVAR 19 10))
MONMSG MSGID(MCH3601)
CHGVAR VAR(&STATUS) VALUE(%SST(&RTNVAR 29 10))
MONMSG MSGID(MCH3601)
CHGVAR VAR(&ACTJOB) VALUE(%BIN(&RTNVAR 73 4))
MONMSG MSGID(MCH3601)
RETURN
ERROR: RCVMSG MSGTYPE(*EXCP) RMV(*NO) KEYVAR(&KEYVAR) +
MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +
MSGFLIB(&MSGFLIB)
SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
MSGDTA(&MSGDTA) TOPGMQ(*PRV) +
MSGTYPE(*ESCAPE) KEYVAR(&KEYVAR)
MONMSG MSGID(CPF0000)
ENDPGM
*****************************************************************************************
CMD PROMPT('Retrieve subsystem information')
PARM KWD(SBS) TYPE(Q1) MIN(1) PROMPT('Name +
subsysteem')
Q1: QUAL TYPE(*NAME)
QUAL TYPE(*NAME) DFT(*LIBL) SPCVAL((*LIBL) +
(*CURLIB)) PROMPT('Library')
PARM KWD(RTNLIB) TYPE(*CHAR) LEN(10) RTNVAL(*YES) +
PROMPT('CL-var for RTNLIB (10)')
PARM KWD(STATUS) TYPE(*CHAR) LEN(10) RTNVAL(*YES) +
PROMPT('CL-var for STATUS (10)')
PARM KWD(ACTJOB) TYPE(*DEC) LEN(5 0) RTNVAL(*YES) +
PROMPT('CL-var for ACTJOB (5 0)')
Record lock shouldn't hurt you, unless you're using commitment control, in which case there's a parameter related to how long to wait for commit boundaries. Unless you've got extremely long running commit cycles, you should still be able to reach a checkpoint in a reasonable amount of time (seconds or minutes).
You may want to review Systems management > Backup and recovery > Backing up your system. Basically all objects are checkpointed, which is the time where they're synchronized. There are several levels of synchronization, which you need to set based on the dependencies between your objects in different libraries. From the checkpoint time until the end of the save, for any storage pages that are changed, the system makes a copy of the storage page. The live page continues with the object. The copy of the page, which is the before version (what it looked like at the time of the checkpoint) is what gets saved. When the save is done, the "before" copies are destroyed, since they were only needed for the save.