简化读取 SMF 以分析数据集生命周期的 DF/Sort 作业

Simplifying a DF/Sort job thats reads SMF to analyse a dataset's lifecycle

所以我有一个批处理作业,它将 SMF 类型 14、15 和 17 的记录提取到 3 个单独的文件中,然后格式化这些文件以生成一个列表,其中列出了哪些作业读取、写入和删除了哪些数据集。然后按时间戳排序,因此您可以看到特定数据集的 'lifecycle'。

但是,我知道 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 是否真的在创建数据集。我还应该添加重命名,否则你可能 忘记了特定数据集发生了什么。

编辑:

按照 Bill 的指导,我的 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  

离开

,CONVERT

给我:

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))    

"Is it possible to do this without separating the 14, 15 and 17 records into separate files?"

根据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))

...会将所有类型合并到一个文件中。

是的,而且相当无痛。

IFTHEN=(WHEN= 允许各种类型的条件处理。

在这里你可以使用 IFTHEN=(WHEN=(logicalexpression) 来创建一个 case/select/evaluate-type 结构:

IFTHEN=(WHEN=(5,1,B,EQ,14),
         ...),
IFTHEN=(WHEN=(5,1,B,EQ,15),
         ...),
IFTHEN=(WHEN=NONE,
         ...)

WHEN=NONE 是 "catch-all",因为前面测试的 none 为真。当一个测试为真时,IFTHEN=(WHEN=(logicalexpression) 停止当前记录。即使当前记录的第二个条件为真,它也不会被执行。如果你想要两个或更多 "hits"在 IFTHEN=(WHEN=(logicalexpression) 那么你必须在每次测试结束时使用 HIT=NEXT ,你可能想要 "pass it on" 到下一个测试。 在这里,这无关紧要,因为它是针对单个值测试的同一字段。

IFTHEN 可以出现在 INRECOUTRECOUTFIL 上。你在 OUTREC 上进行了处理,所以你会(尽管请参阅我后来的评论):

OUTREC IFTHEN=(WHEN=(5,1,B,EQ,14),
                ...),
       IFTHEN=(WHEN=(5,1,B,EQ,15),
                ...),
       IFTHEN=(WHEN=NONE,
                ...)

BUILDOVERLAYPARSE 可以在 IFTHEN 中使用。

一些想法和提示。

我怀疑你的 SUM FIELDS=NONE。这将删除任何具有重复键的记录。保留输入中的哪条记录取决于。如果您在 SORT(或 MERGE)上使用 OPTION EQUALSEQUALS,则将始终保留第一条记录。如果您不这样做,则在密钥重复时保留的记录可能会有所不同 运行 运行。 EQUALS 对性能有一些影响。

无论如何,我不确定为什么你在这里有 FIELDS=NONE。您甚至可以在完全不同的数据集上进行 "accidental" 匹配。

如果您要排序然后 select 仅部分数据(在 OUTREC 或 OUTFIL 中),则始终考虑 "cutting down" 要排序的记录,以便它只包括您稍后将使用的数据。排序时,数据越少,使用的时间、内存和临时存储空间就越少。

考虑使用 DYNAM 作为临时存储,并从 JCL 中删除您的 SORTWKn DD 名称(这里只有一个,但是...)。工作区的动态分配意味着您根本不必考虑工作区(除非您有大量数据记录长度变化很大的数据集)并且您不需要 "overallocate".

排序符号。符号允许您命名您的数据,因此可以通过名称来引用同一字段,并且 SORT 负责每次键入起始位置和长度的不那么令人兴奋的任务。它还减少了所需的注释量,因为该字段已经有一个名称,您可以对其进行描述。

符号在单独的数据集 (F/FB 80) 中定义,带有 SYMNAMES DD。翻译后的符号(也提供了所用内容的记录)保存在 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来完成工作。

如果你想对数据集做selection,你可以看看使用PARM和特殊符号JP0-JP9。或者硬编码。或者从数据集列表生成 SORT 控制卡,或者使用 JOINKEYS.

哦,我知道你知道,但你实际上在使用 SYNCSORT。 DFSORT 在 OUTREC 上没有 CONVERT,但在 OUTFIL 上有。为了便于携带,这里只需将您的 OUTREC 更改为 OUTFIL。

好的 - 在 Bill 的帮助下(他让我接受了他的回答)并且在决定坚持使用手册之后,这是我的结果:

//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 编辑或查看来说太大,否则您可以只编辑输出并在那里进行过滤。