2016-10-15 6 views
3

So habe ich einen Batch-Job, der SMF-Typ 14, 15 und 17 Datensätze in 3 separate Dateien extrahiert und formatiert dann die Dateien, um eine Liste der Datensätze zu erstellen gelesen, geschrieben und gelöscht durch welche Jobs. Dies wird dann nach Zeitstempel sortiert, so dass Sie den "Lebenszyklus" für einen bestimmten Datensatz sehen können.Vereinfachung eines DF/Sort-Jobs, der SMF liest, um den Lebenszyklus einer Datenmenge zu analysieren.

Ich weiß jedoch, dass DF/Sortt ziemlich mächtig ist und ich denke, dass mein erster Schritt, die Typ 14, 15 und 17 Datensätze zu trennen, nicht notwendig ist, und es könnte in einem Schritt gemacht werden, aber ich ' Ich bin nicht wirklich sicher, wo ich anfangen soll, da DFSort/ICETOOL ziemlich anspruchsvoll geworden ist.

Hier ist meine aktuelle 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) 

Es ist möglich, dies zu tun, ohne die 14, 15 und 17 Datensätze in separate Dateien zu trennen?

Edit: die obige JCL tut genau das, was ich wan, aber ich würde in der Lage sein, nach Dataset-Namen oder Job-Namen zu filtern, da dies eine Menge Ausgabe produzieren kann, die dann für ISPF Edit zu groß ist oder Ansicht für eine weitere Analyse

Edit:

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. 

Eine weitere Verbesserung wäre zu prüfen, ob ein OPEN wurde tatsächlich den Datensatz zu erstellen. Ich sollte auch RENAMES hinzufügen, sonst könnten Sie den Überblick darüber verlieren, was mit einem bestimmten Datensatz passiert ist.

Edit:

Richtlinien Bill Folgen, meine JCL ist jetzt:

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

Aber das gibt:

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 

die

Weglassen, CONVERT

gibt mir:

WER235A OUTREC RDW NOT INCLUDED 

Bearbeiten - letzte Änderung:

Nur versuchen, Typ 14 Datensätze zu isolieren, so Stromeingang ist jetzt:

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

Antwort

2

Ja, und es ist ziemlich schmerzlos.

IFTHEN=(WHEN= ermöglicht verschiedene Arten von bedingten Prozess.

Hier können Sie uns das ifthen = (WHEN = (logischer Ausdruck) einen Fall/select/auswerten artige Struktur zu machen:

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

WHEN=NONE ist der "catch-all", denn wenn keiner der vorherige Tests sind wahr IFTHEN = (WHEN = (logischeAusdruck) stoppt für den aktuellen Datensatz, wenn ein Test wahr ist. Selbst wenn eine zweite Bedingung für den aktuellen Datensatz wahr wäre, würde sie nicht bearbeitet. Wenn Sie zwei oder mehr wollen "Hits" in IFTHEN = (WHEN = (logischeAusdruck) dann müssen Sie HIT = NEXT am Ende jedes Tests verwenden, wo Sie vielleicht "weiterleiten" zum nächsten Test. Hier ist das nicht relevant, da es sich um dasselbe Feld handelt, das für einen einzelnen Wert getestet wurde .

IFTHEN kann auf INREC, OUTREC oder OUTFIL erscheinen. Sie haben Ihre Verarbeitung auf OUTREC, so würden Sie haben (obwohl meine späteren Kommentar sehen):

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

BUILD, OVERLAY und PARSE innerhalb ifthen verwendet werden.

Einige Gedanken und Tipps.

Ich bin verdächtig auf Ihre SUM FIELDS=NONE. Dies würde alle Datensätze mit einem doppelten Schlüssel löschen. Welcher der Datensätze von der Eingabe, die beibehalten wird, hängt davon ab. Wenn Sie OPTION EQUALS oder EQUALS auf SORT (oder MERGE) verwenden, wird der erste Datensatz immer beibehalten. Wenn Sie nicht den Datensatz, der beibehalten wird, wenn der Schlüssel dupliziert wird, kann von Lauf zu Lauf variieren. EQUALS hat Auswirkungen auf die Leistung.

Wie auch immer, ich bin mir nicht sicher, warum Sie FIELDS = NONE es hier haben. Sie können sogar eine "zufällige" Übereinstimmung über ganz unterschiedliche Datensätze erhalten.

Wenn Sie SORTIEREN und dann nur einen Teil der Daten auswählen (in OUTREC oder OUTFIL), dann denken Sie immer darüber nach, den zu sortierenden Datensatz zu "beschneiden", damit er nur die Daten enthält, die Sie später benötigen benutzen. Beim SORTieren werden weniger Daten, weniger Zeit, Speicher und temporärer Speicher verwendet.

Verwenden Sie DYNAM für temporäre Speicherung, und entfernen Sie Ihre SORTWKn DD-Namen von der JCL (Sie haben nur eine hier, aber ...). Die dynamische Zuweisung des Arbeitsbereichs bedeutet, dass Sie über den Arbeitsbereich nicht viel nachdenken müssen (es sei denn, Sie haben riesige Datensätze mit sehr unterschiedlichen Datensatzlängen für die Daten) und Sie "nicht überladen".

SORT-Symbole. Mit Symbolen können Sie Ihre Daten benennen, sodass Verweise auf das gleiche Feld nach Namen erfolgen können, und SORT kümmert sich um die weniger spannende Aufgabe, jedes Mal die Startposition und die Länge einzugeben. Es reduziert auch die Anzahl der erforderlichen Kommentare, da das Feld bereits einen Namen hat, den Sie beschreibend machen können.

Symbole werden in einem separaten Datensatz (F/FB 80) mit einem SYMNAMES DD definiert. Die übersetzten Symbole (die auch eine Aufzeichnung dessen enthalten, was verwendet wurde) werden in einem SYMNOUT-Dataset gespeichert, das nicht benötigt wird, aber nützlich ist.

SORT wendet dann die Symbole auf Ihre Steuerkarten an und zeigt Ihnen neben der Originalquelle im SYSOUT auch die übersetzten Karten.

Symbole für diese Aufgabe könnte entlang dieser Linien

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 

Dann angegeben werden Sie mit dem Symbol die mehrere Definitionen des gleichen Feldes ersetzen kann, und lassen Sie die Arbeit SORT tun.

Wenn Sie eine Auswahl für Datensätze treffen möchten, können Sie sich mit dem PARM und den Sonderzeichen JP0 - JP9 befassen. Oder hart codieren. Oder die SORT-Steuerkarten aus einer Liste von Datensätzen generieren oder JOINKEYS verwenden.

Oh, und ich weiß, dass Sie wissen, aber Sie verwenden tatsächlich SYNCSORT. DFSORT hat CONVERT nicht auf OUTREC, aber auf OUTFIL. Um transportabel zu sein, wechseln Sie einfach Ihre OUTREC zu OUTFIL.

2

„Ist es möglich, tun Sie das ohne die 14, 15 und 17 Datensätze in separate Dateien zu trennen? "

Nach http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/BOOKS/IEA2G2C0/3.2.1

... ein DD-Statement

//DUMP DD DISP=(,PASS),... 

... mit einer Steuererklärung

OUTDD(DUMP,TYPE(14,15,17)) 

... würde alle Typen in einer Datei kombinieren .

+1

Hallo David. Ja, aber die Frage ist, wie man die SORT-Anweisungen danach kombiniert. –

+0

David - Ja, jetzt kann ich zwischen den Datensatztypen im Code unterscheiden, ich kann einfach das SMF-Archiv als Eingabe für meine SORT verwenden. Ich habe sie vorher getrennt, damit ich für jeden Typ 3 leicht unterschiedliche Sätze von Steueranweisungen ausführen konnte. –

1

OK - mit Hilfe von Bill (die Antwort, das ich akzeptieren werde, als er hat mich gehen) und nach der Entscheidung trifft in den Handbüchern stecken zu bleiben, das ist mein Ergebnis:

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

I couldn‘ t erarbeiten, wenn es möglich ist, den letzten Schritt in den Hauptschritt zu integrieren, aber ich bin damit zufrieden. Beachten Sie, dass wir Syncsort und nicht DF/Sort verwenden. Beachten Sie daher, dass Änderungen erforderlich sein können, wenn Sie ein DF/Sort-Shop sind. Das INCLUDE COND ist da, weil das Ausgabe-Dataset meistens zu groß für ISPF Edit oder View ist, sonst könnten Sie einfach die Ausgabe editieren und dort filtern.

+1

Die ursprüngliche SORT Ich denke, ist nur da, um die Reihenfolge in der Ausgabe zu steuern, anstatt etwas für die Verarbeitung notwendig (oder dachte notwendig. Zurück zur SUM). Sie könnten SORTIEREN für Ihre endgültige Ausgabe und INCLUDE = auf OUTFIL verwenden, um diese Auswahl zu treffen. Wenn Sie jedoch die Daten mit dem ersten Schritt "vorbereiten" und verschiedene Läufe des FINALs durchführen, sollten Sie sie besser aufteilen. Denken Sie daran, die Symbole können auch in FINAL helfen. –

+1

@BillWoodger - in der Tat - dies wird von einem ISPF-Panel gesteuert, so werde ich wahrscheinlich eine Option hinzufügen, um den SMF-Extrakt zu speichern und dann einen anderen "PROCESS" -Schritt dagegen ausführen, um den möglicherweise langwierigen SMF-Schritt zu speichern. –

+0

@Bill - Ich habe gerade festgestellt, dass ich einen 'Filter'-Schritt vor der Hauptsortierung mit den Suchargumenten haben sollte, um die Menge der zu sortierenden Daten zu reduzieren. Ich habe eine Verkürzung der verstrichenen Zeit von 32% (12,91 Minuten auf 8,89) –

Verwandte Themen