I am fairly new to JCL and REXX, and was handed off a project to send RACF log data to a program called SPLUNK. They handed me a bunch of code, said it worked, and told me to set up a job in ESP to submit. I did that, but when looking at the output, I am sending a lot of redundant data that I don't want to keep sending every 15 minutes, every day. I am looking to try and implement some sort of time variable so the only records grabbed would fall within the last 15 minutes (since the job runs every 15 minutes). I'll post the code and show what they gave me:
This is the JCL:
//DXZ4JOBC JOB (SCRUBBED),'COMPSCIGUI',
// MSGLEVEL=1,MSGCLASS=T,PRTY=10,TIME=5
//*EXEC CNTR3
//*MAIN ORG=CNTR3,CLASS=BATCH
//OPERSCAN EXEC OPERLOGP
//OPRDATA DD DISP=SHR,DSN=DX.D945.OPERLOG3
//PRTOLOG DD DSN=&&OLOGOUT,UNIT=DISK,SPACE=(CYL,(100,100)),
// DISP=(,PASS),DCB=LRECL=133
//OPRPARMS DD *
REPORT PRTOLOG
TIME 0000 2359
MESSAGE ICH70001I
MESSAGE ICH408I
//*
//* PARSE THE OLOG OUTPUT TO COMBINE ICH408I MESSAGES ONTO
//* A SINGLE LINE.
//*
//PARSE EXEC PGM=IRXJCL,DYNAMNBR=50,REGION=6000K,
// PARM='AUTHPARS'
//SYSTSPRT DD SYSOUT=*
//MESSAGES DD DSN=&&OLOGOUT,DISP=SHR
//OUTDD DD DSN=&&AUTHOUT,UNIT=DISK,SPACE=(CYL,(100,100)),
// DISP=(,PASS),DCB=LRECL=500
//SYSTSIN DD DUMMY
//SYSEXEC DD DSN=SCRUBBED.REXX.EXEC,DISP=SHR
//*
//* UNCOMMENT TO WRITE A SECOND COPY TO THE JOB SYSOUT */
//*
//IEBCOPY EXEC PGM=IEBGENER
//SYSUT1 DD DSN=&&AUTHOUT,DISP=(SHR,PASS)
//SYSUT2 DD SYSOUT=(,)
//SYSPRINT DD SYSOUT=(,)
//SYSIN DD DUMMY
//*
//* TRANSMIT THE MESSAGES TO THE SPLUNK SERVER USING SYSLOG
//*
//TRANSMIT EXEC PGM=IRXJCL,DYNAMNBR=50,REGION=6000K,
// PARM='SPLUNKER IP ADDRESS SCRUBBED'
//SYSTSPRT DD SYSOUT=*
//MESSAGES DD DSN=&&AUTHOUT,DISP=SHR
//SYSTSIN DD DUMMY
//SYSEXEC DD DSN=SCRUBBED.REXX.EXEC,DISP=SHR
// MSGLEVEL=1,MSGCLASS=T,PRTY=10,TIME=5
//*EXEC CNTR3
//*MAIN ORG=CNTR3,CLASS=BATCH
//OPERSCAN EXEC OPERLOGP
//OPRDATA DD DISP=SHR,DSN=DX.D945.OPERLOG3
//PRTOLOG DD DSN=&&OLOGOUT,UNIT=DISK,SPACE=(CYL,(100,100)),
// DISP=(,PASS),DCB=LRECL=133
//OPRPARMS DD *
REPORT PRTOLOG
TIME 0000 2359
MESSAGE ICH70001I
MESSAGE ICH408I
//*
//* PARSE THE OLOG OUTPUT TO COMBINE ICH408I MESSAGES ONTO
//* A SINGLE LINE.
//*
//PARSE EXEC PGM=IRXJCL,DYNAMNBR=50,REGION=6000K,
// PARM='AUTHPARS'
//SYSTSPRT DD SYSOUT=*
//MESSAGES DD DSN=&&OLOGOUT,DISP=SHR
//OUTDD DD DSN=&&AUTHOUT,UNIT=DISK,SPACE=(CYL,(100,100)),
// DISP=(,PASS),DCB=LRECL=500
//SYSTSIN DD DUMMY
//SYSEXEC DD DSN=SCRUBBED.REXX.EXEC,DISP=SHR
//*
//* UNCOMMENT TO WRITE A SECOND COPY TO THE JOB SYSOUT */
//*
//IEBCOPY EXEC PGM=IEBGENER
//SYSUT1 DD DSN=&&AUTHOUT,DISP=(SHR,PASS)
//SYSUT2 DD SYSOUT=(,)
//SYSPRINT DD SYSOUT=(,)
//SYSIN DD DUMMY
//*
//* TRANSMIT THE MESSAGES TO THE SPLUNK SERVER USING SYSLOG
//*
//TRANSMIT EXEC PGM=IRXJCL,DYNAMNBR=50,REGION=6000K,
// PARM='SPLUNKER IP ADDRESS SCRUBBED'
//SYSTSPRT DD SYSOUT=*
//MESSAGES DD DSN=&&AUTHOUT,DISP=SHR
//SYSTSIN DD DUMMY
//SYSEXEC DD DSN=SCRUBBED.REXX.EXEC,DISP=SHR
Here is the REXX:
TRACE N /* TRACE I - verbose, R - intermediate, N - normal, E - errors */
/* Parse and display the parameters passed by the batch job */
parse arg ipaddress port
say 'Endpoint -' ipaddress':'port
/* Read all records from the MESSAGES DD into a stem variable */
"EXECIO * DISKR messages (STEM records."
return_code = RC
SAY records.0 ' records read'
/* Initialize */
call Socket 'Initialize', 'SPLUNKER'
if src=0 then initialized = 1
else call error 'E', 200, 'Unable to initialize SOCKET'
if server='' then do
server = Socket('GetHostId')
if src¬=0 then call error 'E', 200, 'Cannot get the local ipaddress'
end
/* Initialize for receiving lines sent by the server */
s = Socket('Socket') /* Would add ,DATAGRAM type here if UDP */
if src¬=0 then call error 'E', 32, 'SOCKET(SOCKET) rc='src
hostname = translate(Socket('GetHostName'))
if src¬=0 then call error 'E', 32, 'SOCKET(GETHOSTNAME) rc='src
call Socket 'Connect', s, 'AF_INET' port ipaddress
if src¬=0 then call error 'E', 32, 'SOCKET(CONNECT) rc='src
call Socket 'SetSockOpt', s, 'SOL_SOCKET', 'SO_ASCII', 1
crlf="0D"X /* store a literal for the end of record character */
/* Loop to write records to the server */
DO i = 1 to records.0
sendstring = strip(records.i)
call Socket 'Write', s, sendstring
if src¬=0 then call error 'E', 32, 'SOCKET(WRITE) rc='src
call Socket 'Write', s, crlf
if src¬=0 then call error 'E', 32, 'SOCKET(WRITE) rc='src
END
/* Terminate and exit */
call Socket 'Terminate'
exit 0
EXIT return_code
socket: procedure expose src
a0 = arg(1)
a1 = arg(2)
a2 = arg(3)
a3 = arg(4)
a4 = arg(5)
a5 = arg(6)
a6 = arg(7)
a7 = arg(8)
a8 = arg(9)
a9 = arg(10)
parse value 'SOCKET'(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9) with src res
return res
/* Syntax error routine */
syntax:
call error 'E', rc, '==> REXX Error No.' 20000+rc
return
/* Halt processing routine */
halt:
call error 'E', 4, '==> REXX Interrupted'
return
/* Error message and exit routine */
error:
type = arg(1)
retc = arg(2)
text = arg(3)
ecretc = right(retc,3,'0')
ectype = translate(type)
ecfull = 'RXSCLI' || ecretc || ectype
say '===> Error:' ecfull text
if type¬='E' then return
if initialized
then do
parse value Socket('SocketSetStatus') with . status severreason
if status¬='Connected'
then say 'The status of the socket set is' status severreason
end
call Socket 'Terminate'
exit retc
Right now is grabs everything every time the job submits, and I can't keep doing that. Any help would be greatly appreciated, as I am new to this and stuck.
Thanks