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

标签 mainframe jcl dfsort

所以我有一个批处理作业,它将 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 是否真的在创建数据集。我还应该添加重命名,否则你可能 无法跟踪特定数据集发生了什么。

编辑:

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

最佳答案

是的,而且相当轻松。

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

在这里您可以使用 IFTHEN=(WHEN=(logicalexpression) 来创建 case/select/evaluate 类型的结构:

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 ,你可能希望将它“传递”到下一个测试。 在这里,这无关紧要,因为它是针对单个值测试的同一字段。

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,那么第一条记录将始终保留.如果您不这样做,则在 key 重复时保留的记录可能会因运行而异。 EQUALS 对性能有一些影响。

无论如何,我不确定你为什么在这里设置 FIELDS=NONE。您甚至可以在完全不同的数据集中获得“意外”匹配。

如果您要进行排序,然后只选择部分数据(在 OUTREC 或 OUTFIL 中),则始终考虑“削减”要排序的记录,以便它仅包含您稍后将使用的数据.排序时,数据越少,使用的时间、内存和临时存储空间就越少。

考虑使用 DYNAM 进行临时存储,并从 JCL 中删除您的 SORTWKn DD 名称(这里只有一个,但是...)。工作空间的动态分配意味着您完全不必考虑工作空间(除非您拥有大量数据记录长度变化很大的数据集)并且您不会“过度分配”。

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

符号在带有 SYMNAMES DD 的单独数据集 (F/FB 80) 中定义。翻译后的符号(也提供了所用内容的记录)保存在 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 在 OUTREC 上没有 CONVERT,但在 OUTFIL 上有。为了方便携带,只需将您的 OUTREC 更改为 OUTFIL。

关于mainframe - 简化读取 SMF 以分析数据集生命周期的 DF/Sort 作业,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40061231/

相关文章:

mainframe - 如何在 SORT 操作中减少 CPU

JCL ICEMAN 需要多少排序文件?

mainframe - 有人还在用 ObjectStar 编程吗(以前称为 Huron)

unix - PL/I 程序中的 z/OS MVS 和 z/OS UNIX 互操作?

hadoop - 如何将数据从大型机拉取到 Hadoop

java - 如何通过 Java web 应用程序在 IBM z OS 中提交 JCL?

jcl - 身份不明的操作领域 JCL

ftp - ftping 到 MainFrame 时如何计算存储空间

console-application - 在大型机 COBOL 中,如何向控制台运算符(operator)发送消息,等待响应,然后继续?