Упрощение задания DF/Sort с чтением SMF для анализа жизненного цикла набора данных
Таким образом, у меня есть пакетное задание, которое извлекает записи SMF типа 14, 15 и 17 в 3 отдельных файла, а затем форматирует файлы, чтобы получить список наборов данных, которые были прочитаны, записаны и удалены какими заданиями. Затем он сортируется по отметке времени, чтобы вы могли увидеть "жизненный цикл" для определенного набора данных.
Тем не менее, я знаю, что DF/Sortt довольно мощный, и я думаю, что мой начальный шаг по разделению записей типов 14, 15 и 17 не является необходимым, и это можно сделать за один шаг, но я не совсем уверен с чего начать, так как DFSort/ICETOOL стал довольно сложным.
Вот мой текущий JCL:
//JBSP03DL JOB (JSDBBSP,P10),'SMF F NOW',
// NOTIFY=&SYSUID,
// CLASS=L,
// MSGCLASS=X,
// REGION=8M
//*
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA
//*
//SMFDUMP EXEC PGM=IFASMFDP,REGION=6M
//*
//SYSPRINT DD SYSOUT=*
//* Extract type 14, 15 and 17 records into 3 temporary datasets
//DUMPIN DD DISP=SHR,DSN=JSHSMF.SMF.JXSF.MANDUMP
//*
//DUMP14 DD DISP=(,PASS),DSN=&&TYPE14,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//DUMP15 DD DISP=(,PASS),DSN=&&TYPE15,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//DUMP17 DD DISP=(,PASS),DSN=&&TYPE17,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,BLKSIZE=27998,LRECL=32760,RECFM=VBS
//*
//SYSIN DD *
INDD(DUMPIN,OPTIONS(DUMP))
OUTDD(DUMP14,TYPE(14))
OUTDD(DUMP15,TYPE(15))
OUTDD(DUMP17,TYPE(17))
//*
//SORTPROC PROC
//SORTWRTE EXEC PGM=SORT,REGION=8M
//SORTOUT DD DISP=MOD,DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SORTWK01 DD DISP=(NEW,DELETE),DSN=&&TEMPSORT,UNIT=SYSDA,
// SPACE=(CYL,(50,50))
// PEND
//*
//* Process the type 14 records
//TYPE14 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE14
//SORTOUT DD DISP=(,PASS),DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA,
// LRECL=133
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
69,44,
C' was opened by ',
19,8),CONVERT
//*
//* Process the type 15 records
//TYPE15 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE15
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
19,8,
C' opened ',
69,44,
C' for output'),CONVERT
//*
//* Process the type 17 records
//TYPE17 EXEC SORTPROC
//SORTIN DD DISP=SHR,DSN=&&TYPE17
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
SUM FIELDS=NONE
OUTREC BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT), DATE OF RECORD
C' AT ',
7,4,TM4,EDIT=(TT:TT:TT.TT), TIME OF RECORD
C' ',
19,8,
C' deleted ',
44,44),CONVERT
//*
//* Finally sort the output file by the date & time stamp
//*
//FINAL EXEC SORTPROC
//SORTIN DD DISP=(OLD,DELETE),DSN=&&SORTTMP
//SORTOUT DD DISP=(NEW,CATLG),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA,LRECL=121,RECFM=FB,SPACE=(CYL,(20,30))
//SYSIN DD *
SORT FIELDS=(1,23,CH,A)
Можно ли это сделать, не разделяя записи 14, 15 и 17 на отдельные файлы?
Редактировать: вышеупомянутый JCL делает именно то, что я хочу, но я хотел бы иметь возможность фильтровать по имени набора данных или имени задания, если это возможно, так как это может привести к большому выводу, который затем будет слишком большим для редактирования или просмотра ISPF для дальнейшего использования. анализ
Редактировать:
Type 14 :
5 5 SMF14RTY 1 binary Record type 14 (X'0E').
18 12 SMF14JBN 8 EBCDIC Job name.
68 44 SMF14_JFCBDSNM 44 EBCDIC DATA SET NAME (DSNAME=)
Type 15 :
5 5 SMF14RTY 1 binary Record type 14 (X'0F').
18 12 SMF15JBN 8 EBCDIC Jobname
68 44 SMF15_JFCBDSNM 44 EBCDIC DATA SET NAME (DSNAME=)
Type 17:
5 5 SMF17RTY 1 binary Record type 17 (X'11').
18 12 SMF17JBN 8 EBCDIC Job name.
44 2C SMF17DSN 44 EBCDIC Data set name.
Еще одним улучшением будет проверка того, действительно ли OPEN создает набор данных. Я также должен добавить RENAMES, иначе вы можете потерять отслеживание того, что случилось с конкретным набором данных.
Редактировать:
Следуя указаниям Билла, мой JCL теперь:
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// UNIT=SYSDA
//*
//SORTWRTE EXEC PGM=SORT,REGION=8M
//*
//SORTIN DD DISP=SHR,DSN=JSHSMF.SMF.JXSG.MANDUMP
//SORTOUT DD DISP=(MOD,CATLG),DSN=JSDBSP.JBSP03.DSLIFE.TXT,
// SPACE=(CYL,(20,20)),
// UNIT=SYSDA,LRECL=133
//*
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYMNOUT DD SYSOUT=*
//SYMNAMES DD *
SMF-RECORD-TYPE,5,1,BI
SMF-JOB-NAME,19,8,CH
SMF-14-15-DSN,69,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
//*
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTREC IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME)),CONVERT
Но это дает:
OUTREC IFTHEN=(WHEN=(5,1,BI,EQ,14),BUILD=(11,4,DT1,EDIT=(TTTT-TT-TT),C' AT ',7,4
,TM4,EDIT=(TT:TT:TT.TT),C' ',69,44,C' was opened by ',19,8)),CONVERT
*
WER268A OUTREC STATEMENT : SYNTAX ERROR
Оставляя
,ПЕРЕРАБАТЫВАТЬ
дает мне:
WER235A OUTREC RDW NOT INCLUDED
Редактировать - последнее обновление:
Просто пытаюсь изолировать записи типа 14, поэтому текущий ввод теперь:
//SYMNAMES DD *
SMF-RECORD-TYPE,6,1,BI
SMF-JOB-NAME,11,8,CH
SMF-14-15-DSN,65,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTFIL IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(1,4,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME))
3 ответа
Да, и это довольно безболезненно.
IFTHEN=(WHEN=
допускаются различные виды условного процесса.
Здесь вы можете использовать IFTHEN=(WHEN=(logicalexpression), чтобы создать структуру case/select/valu-type:
IFTHEN=(WHEN=(5,1,B,EQ,14),
...),
IFTHEN=(WHEN=(5,1,B,EQ,15),
...),
IFTHEN=(WHEN=NONE,
...)
WHEN=NONE
является "ловушкой", когда ни один из предыдущих тестов не соответствует действительности. IFTHEN=(WHEN=(logicalexpression) останавливается для текущей записи, когда один тест является истинным. Даже если второе условие для текущей записи должно быть истинным, оно не будет выполнено. Если вы хотите два или более "попаданий" в IFTHEN=(WHEN=(logicalexpression), тогда вы должны использовать HIT=NEXT в конце каждого теста, где вы можете захотеть "передать его" следующему тесту. Здесь это не имеет значения, так как это то же поле проверено на одно значение.
ЕСЛИ может появиться на INREC
, OUTREC
, или же OUTFIL
, У вас есть обработка на OUTREC, так что вы бы (хотя см. Мой более поздний комментарий):
OUTREC IFTHEN=(WHEN=(5,1,B,EQ,14),
...),
IFTHEN=(WHEN=(5,1,B,EQ,15),
...),
IFTHEN=(WHEN=NONE,
...)
BUILD
, OVERLAY
а также PARSE
можно использовать в IFTHEN.
Несколько мыслей и советов.
Я с подозрением отношусь к вашему SUM FIELDS=NONE
, Это приведет к удалению любых записей с дубликатом ключа. Какая из записей из входного файла, который сохраняется, зависит. Если вы используете OPTION EQUALS
или же EQUALS
на SORT
(или же MERGE
) тогда первая запись всегда будет сохранена. Если вы этого не сделаете, запись, которая сохраняется, когда ключ дублируется, может варьироваться от запуска к запуску. РАВНЫЕ имеет некоторое влияние на производительность.
Во всяком случае, я не уверен, почему у вас есть поля = нет здесь. Вы даже можете получить "случайное" совпадение для совершенно разных наборов данных.
Если вы собираетесь выполнить сортировку, а затем выбрать только часть данных (в OUTREC или OUTFIL), всегда рассматривайте возможность "вырезания" записи, которая должна быть отсортирована, чтобы она включала в себя только те данные, которые вы позже будете использовать. При сортировке, чем меньше данных, тем меньше времени, памяти и временного хранилища используется.
Рассмотреть возможность использования DYNAM
для временного хранения, и удалите SORTWKn
ДД имена из JCL (у вас есть только один здесь, но...). Динамическое выделение рабочего пространства означает, что вам вообще не нужно много думать о рабочем пространстве (если только у вас нет огромных наборов данных с широко варьируемыми длинами записей для данных), и вы не "перераспределяете".
Сортировка символов. Символы позволяют вам называть ваши данные, так что ссылки на одно и то же поле могут быть сделаны по имени, и SORT заботится о менее захватывающей задаче - вводить начальную позицию и длину каждый раз. Это также уменьшает количество необходимых комментариев, потому что поле уже имеет имя, которое вы можете сделать описательным.
Символы определяются в отдельном наборе данных (F/FB 80) с DD SYMNAMES. Переведенные символы (которые также предоставляют запись о том, что использовалось) содержатся в наборе данных SYMNOUT, который не является обязательным, но полезен.
SORT затем применяет символы к вашим контрольным картам, а также показывает ваш исходный источник в SYSOUT, показывает вам переведенные карты.
Символы для этой задачи могут быть указаны вдоль этих линий
SMF-RECORD-TYPE,5,1,BI
SMF-JOB-NAME,18,8,CH
SMF-14-15-DSN,68,44,CH
SMF-17-DSN,44,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
Затем вы можете заменить несколько определений одного и того же поля символом, и пусть SORT сделает всю работу.
Если вы хотите сделать выборку для наборов данных, вы можете посмотреть на использование PARM и специальных символов JP0
-JP9
, Или жесткий код Или создание контрольных карт SORT из списка наборов данных, или с помощью JOINKEYS
,
О, и я знаю, что вы знаете, но вы на самом деле используете SYNCSORT. DFSORT не имеет CONVERT
на OUTREC, но это на OUTFIL. Чтобы быть транспортабельным, просто измените ваш OUTREC на OUTFIL.
"Можно ли сделать это, не разделяя записи 14, 15 и 17 на отдельные файлы?"
Согласно http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA2G2C0/3.2.1
... заявление DD
//DUMP DD DISP=(,PASS),...
... с контрольной выпиской
OUTDD(DUMP,TYPE(14,15,17))
... объединит все типы в один файл.
ОК - с помощью Билла (чей ответ я принимаю, когда он меня заставил) и после принятия решения застрять в руководствах, это мой результат:
//jobname JOB (acct_code),'pgmr_name',
// NOTIFY=&SYSUID,
// CLASS=L,
// MSGCLASS=X,
// REGION=8M
//*
// SET OUTFILE=your.results.file
//*
//DELETE EXEC PGM=IEFBR14
//OUTDSN DD DISP=(MOD,DELETE),DSN=&OUTFILE,
// UNIT=SYSDA
//*
//SMFDUMP EXEC PGM=IFASMFDP,REGION=6M
//*
//SYSPRINT DD SYSOUT=*
//*
//DUMPIN DD DISP=SHR,DSN=your.smf.dataset
//*
//DUMPOUT DD DISP=(,PASS),DSN=&&SMFTEMP,
// UNIT=SYSDA,SPACE=(CYL,(500,200),RLSE),
// BUFNO=20,DCB=*.DUMPIN
//*
//SYSIN DD *
INDD(DUMPIN,OPTIONS(DUMP))
OUTDD(DUMPOUT,TYPE(14,15,17,18))
//*
//SORTPROC PROC
//SORTWRTE EXEC PGM=SORT,REGION=8M
//SORTIN DD DUMMY
//SORTOUT DD DUMMY
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYMNAMES DD *
RDW,1,4,BI
SMF-RECORD-TYPE,6,1,BI
SMF-JOB-NAME,19,8,CH
SMF-14-15-DSN,69,44,CH
SMF-17-18-DSN,45,44,CH
SMF-17-DSN,45,44,CH
SMF-18-DSN,45,44,CH
SMF-18-NDSN,89,44,CH
SMF-DATE,11,4,DT1
SMF-TIME,7,4,TM4
SMFDEBOP,253,1
// PEND
//*
//PROCESS EXEC SORTPROC
//SORTIN DD DISP=OLD,DSN=&&SMFTEMP
//SORTOUT DD DISP=(,PASS),DSN=&&SORTTMP,
// SPACE=(CYL,(20,20)),UNIT=SYSDA
//SYSIN DD *
SORT FIELDS=(11,4,PD,A,7,4,PD,A)
OUTREC IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,14),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-14-15-DSN,
C' was opened by ',
SMF-JOB-NAME)),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,15),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' opened ',
SMF-14-15-DSN,
C' for output')),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,17),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' deleted ',
SMF-17-DSN)),
IFTHEN=(WHEN=(SMF-RECORD-TYPE,EQ,18),
BUILD=(RDW,SMF-DATE,EDIT=(TTTT-TT-TT),
C' AT ',
SMF-TIME,EDIT=(TT:TT:TT.TT),
C' ',
SMF-JOB-NAME,
C' renamed ',
SMF-18-DSN,
C' to ',
SMF-18-NDSN))
//*
//FINAL EXEC SORTPROC
//SORTIN DD DISP=OLD,DSN=&&SORTTMP
//SORTOUT DD DSN=&OUTFILE,
// DISP=(NEW,CATLG),UNIT=SYSDA,SPACE=(CYL,(20,30),RLSE)
//SYSIN DD *
OPTION VLSHRT,VLSCMP
SORT FIELDS=(5,25,CH,A)
INCLUDE COND=(1,125,SS,EQ,C'PEEL',
AND,
1,125,SS,EQ,C'XCOM')
OUTFIL FNAMES=SORTOUT,VTOF,OUTREC=(5,126)
Я не мог понять, можно ли было включить заключительный шаг в основной шаг, но я доволен этим, как есть. Обратите внимание, что на самом деле мы используем Syncsort, а не DF/Sort, поэтому помните, что изменения могут потребоваться, если вы работаете в DF / Sort.
INCLUDE COND присутствует, потому что большую часть времени выходной набор данных слишком велик для редактирования или просмотра ISPF, в противном случае вы можете просто отредактировать выходные данные и отфильтровать их там.