//* job card and other control statements here //* //STEP1 EXEC sasproc //SYSIN DD DATA,DLM='@@' /*********************************************************************/ /* */ /* THIS JOB READS SMF RECORDS CREATED BY SAS (IF THE SAS SVC IS */ /* INSTALLED AND THE SMF OPTION IS TURNED ON) AND CREATES A SIMPLE */ /* REPORT OF WHAT JOBS AND/OR USERIDS ARE USING WHICH SAS PRODUCTS. */ /* */ /*********************************************************************/ /*********************************************************************/ /* THIS MACRO IS FOR READING AND FORMATTING THE SAS USER SMF RECORD. */ /* */ /* PARMS: SMFTYPE (KEYWORD REQUIRED) DEFAULT IS 128 */ /* THE SAS SMF RECORD TYPE USED AT THE SITE INSTALLATION. */ /* SMFUSER (KEYWORD OPTIONAL) DEFAULT IS Y */ /* THE SMFUSER FIELD IS READ AS A STRING AND THEN IS PARSED */ /* INTO INDIVIDUAL VARIABLE IF THE LENGTH MATCHES WHAT IS */ /* CREATED BY THE SUPPLIED SAS SMFEXIT ROUTINE. */ /* SMFDD (KEYWORD REQUIRED) DEFAULT IS SASSMF */ /* IDENTIFIES THE DDNAME WHERE THIS PROGRAM IS TO READ THE */ /* RAW SMF DATA. */ /* SASLIB (KEYWORD OPTIONAL) DEFAULT IS WORK */ /* IDENTIFIES THE DDNAME WHERE THIS PROGRAM IS TO WRITE THE */ /* SAS DATASET SASSMF. */ /* */ /* RQMTS:-SMFTYPE MUST SPECIFY THE CORRECT SAS USER SMF RECORD TYPE. */ /* IF THE VALUE USED IS FOR ANOTHER PROGRAM PRODUCT THEN THIS */ /* PROGRAM WILL FAIL. MOST LIKELY FAILURE WILL BE INVALID DATA*/ /* MESSAGES. */ /* -SMFUSER HAS NO REAL REQUIREMENTS OTHER THAN IF THE LENGTH */ /* OF THE USER AREA IS 64 THEN THIS PROGRAM ASSUMES IT IS THE */ /* DATA GENERATED IN THE SAS 9.1.3 AND BEYOND SAS SMFEXIT. IF */ /* THIS PRESENTS A PROBLEM, THIS LOGIC CAN EASILY BE COMMENTED*/ /* OUT BELOW. (IF COLSLEFT = 64 THEN) */ /* -SMFDD MUST POINT TO THE CORRECT DDNAME WHERE THE SMF DATA */ /* IS TO BE READ OR THIS PROGRAM WILL FAIL. */ /* -SASLIB IF OTHER THAN WORK SHOULD HAVE BEEN ALLOCATED OR */ /* THIS PROGRAM WILL FAIL. */ /* */ /* OUTPUT: A DATASET &SASLIB.SASSMF IS CREATED. BY DEFAULT &SASLIB */ /* IS WORK WHICH IS TEMPORARY. PROGRAMMER MUST DETERMINE IF */ /* THEY WILL REPORT DIRECTLY FROM THIS DATASET, MODIFY IT */ /* AND/OR REDIRECT IT. */ /* */ /* EXAMPLES: */ /* TAKING ALL DEFAULTS. SAS WILL READ FROM SASSMF DD, EXPECTING SAS */ /* USER SMF RECORD TYPE 128, WRITE SASSMF DATASET TO THE WORK LIBRARY*/ /* AND KEEP THE SMFUSER FIELD. */ /* %SMFREAD; */ /* */ /* OVERRIDE OUTPUT LOCATION FOR SASSMF DATASET, READ SAS SMF RECORD */ /* TYPE 128 FROM THE SASSMF DD. */ /* LIBNAME SMFIN '.SASSMF.SASLIB'; *OR ALLOCATE IN JCL; */ /* %SMFREAD(SASLIB=SMFIN); */ /* */ /* OVERRIDE INPUT REFERENCE FOR SMF DATA, OUTPUT REFERENCE FOR SASSMF*/ /* DATASET AND IDENTIFY SAS SMF RECORD TYPE AS 222. */ /* FILENAME SMF 'SYS1.MAN1'; *OR ALLOCATE IN JCL; */ /* LIBNAME SMFIN '.SASSMF.SASLIB'; *OR ALLOCATE IN JCL; */ /* %SMFREAD(SMFDD=SMF,SASLIB=SMFIN,SMFTYPE=222); */ /* */ /*********************************************************************/ /* ALLOCATE THE SMF DATA FILE WHERE SMFREAD WILL FIND YOUR SAS SMF */ /* RECORDS - OR ALLOCATE VIA JCL IF ON TAPE */ FILENAME SASSMF 'your.smf.data' DISP=SHR; /* SPECIFY THE SMF RECORD TYPE THAT SAS IS CREATING. THIS IS */ /* CONTROLLED BY THE VALUE OF THE OPTION SMFTYPE IN YOUR CONFIG */ /* FILE OR IN YOUR RESTRICTED OPTIONS TABLE. */ %LET SMFRECNO = 128; %MACRO SMFREAD(SMFTYPE=128,SMFUSER=Y,SMFDD=SASSMF,SASLIB=WORK); %PUT *********************************************************; %PUT SAS IS ABOUT TO PROCESS SMF DATA AS FOLLOWS:; %PUT SAS SMF DATA TO BE READ FROM FILE ALLOCATED TO DD: &SMFDD; %PUT SAS OUTPUT DATASET SASSMF WILL BE WRITTEN TO DD: &SASLIB; %PUT SAS SMF RECORD TYPE DEFINED FOR THIS RUN IS: &SMFTYPE; %PUT *********************************************************; DATA &SASLIB..SASSMF(DROP=COLSLEFT ONEBYTE SMFRSVD %IF %SUBSTR(%UPCASE(&SMFUSER),1,1) NE Y %THEN SMFUSER;); LENGTH SMFRDT SMFDT 8 SMFSID $4 SMFJOBN $8 SMFSTEP 8 SMFPROC $8 SMFCORE 8 SMFCOREK $8 SMFEXCP SMFCPU SMFVUSE SMFVAFF SMFHSP 8 SMFSASRL SMFJUID SMFJOBID $8; FORMAT SMFRDT SMFDT DATETIME21.2 SMFCPU SMFVUSE SMFVAFF SMFHSP TIME12.2; INFILE &SMFDD LENGTH=RECLEN COL=COL STOPOVER; INPUT @1 ONEBYTE $CHAR1. @; /*IS IT LONG ENOUGH TO BE A SAS USER SMF RECORD*/ IF RECLEN GE 64 THEN DO; INPUT @2 SMFRTYP PIB1. @; /*IS IT THE STATED SAS USER SMF RECORD TYPE*/ IF SMFRTYP EQ &SMFTYPE THEN DO; INPUT SMFDT SMFSTAMP8. SMFSID $CHAR4. SMFJOBN $CHAR8. SMFRDT SMFSTAMP8. SMFSTEP PIB1. SMFRSVD PIB1. SMFPROC $CHAR8. SMFCPU TU4. SMFEXCP PIB4. SMFCORE PIB4. SMFVUSE PIB4.2 SMFVAFF PIB4.2 SMFHSP PIB4.2 @; SMFCOREK=COMPRESS(PUT(INT(SMFCORE/1024),8.)||'K'); COLSLEFT=RECLEN-COL+1; /*IS THERE A USER AREA IN THIS SAS USER SMF RECORD*/ IF COLSLEFT LE 100 THEN DO; INPUT SMFUSER $VARYING100. COLSLEFT; /*IS IT MAYBE THE USER AREA SUPPLIED IN DISTRIBUTED SMFEXIT*/ IF COLSLEFT EQ 64 THEN DO; SMFSASRL=SUBSTR(SMFUSER,14,8); SMFJUID=SUBSTR(SMFUSER,33,8); SMFJOBID=SUBSTR(SMFUSER,52,8); END; END; END; ELSE DELETE; /*LONG ENOUGH BUT IS NOT THE STATED SAS SMF RECORD TYPE*/ END; ELSE DELETE; /*NOT LONG ENOUGH TO READ AS A SAS SMF RECORD SO DELETE*/ RUN; %MEND SMFREAD; %SMFREAD; /*********************************************************************/ /* THE FOLLOWING STEPS WILL USE THE SAS SMF DATA SET CREATED BY */ /* THE SMFREAD MACRO TO CREATE A SAS PRODUCT USAGE REPORT. */ /* THE SMF DATA SET WILL BE PROCESSED AGAINST THE PROVIDED SAS */ /* PROCEDURES TABLE TO DETERMINE WHAT SAS PRODUCTS WERE USED. */ /* */ /* OUTPUT: PRODUCT USEAGE REPORT */ /* */ /*********************************************************************/ /* MAP THE PROCEDURES TO THEIR ASSOCIATED PRODUCTS */ DATA WORK.PRODUCT (INDEX=(SMFPROC)); INPUT @1 SMFPROC $8. @1 PROCNAME $13. @14 PROD $CHAR40.; CARDS; ACCESS ACCESS DBF ACCESS DBLOAD ACCESS DB2EXT ACCESS DB2LOAD ACCESS DB2UTIL ACCESS DIF ACCESS QUEST ACCESS SQLEXT ACCESS SQLLOAD ACCESS SQLUTIL ACCESS BUILD AF APPEND BASE BMDP BASE CALENDAR BASE CATALOG BASE CHART BASE CIMPORT BASE COMPARE BASE CONTENTS BASE CONVERT BASE COPY BASE CORR BASE CPORT BASE C16PORT BASE CV2VIEW BASE DATASETS BASE DBCSTAB BASE DISPLAY BASE DOCUMENT BASE EXPLODE BASE EXPORT BASE FORMAT BASE FORMS BASE FREQ BASE FSDEVICE BASE FSLIST BASE IMPORT BASE MEANS BASE MIGRATE BASE ODBCSERVER BASE OPTIONS BASE OPTLOAD BASE OPTSAVE BASE PDS BASE PDSCOPY BASE PLOT BASE PMENU BASE PRINT BASE PRINTTO BASE PRTDEF BASE QPRINT BASE RANK BASE REGISTRY BASE RELEASE BASE REPORT BASE SORT BASE SOURCE BASE SPELL BASE SQL BASE STANDARD BASE SUMMARY BASE SYLK BASE TABULATE BASE TAPECOPY BASE TAPELABEL BASE TIMEPLOT BASE TRANSPOSE BASE TRANTAB BASE UNIVARIATE BASE V5TOV6 BASE XCOPY BASE CALC CALC DOMAIN CONNECT DOWNLOAD CONNECT UPLOAD CONNECT KBA ENGLISH ASSOCIATION ENTERPRISE MINER DECIDE ENTERPRISE MINER DMDB ENTERPRISE MINER DMINE ENTERPRISE MINER DMREG ENTERPRISE MINER DMSPLIT ENTERPRISE MINER NEURAL ENTERPRISE MINER RULEGEN ENTERPRISE MINER SEQUENCE ENTERPRISE MINER SPLIT ENTERPRISE MINER ARIMA ETS AUTOREG ETS CITIBASE ETS COMPUTAB ETS DATASOURCE ETS DLREG ETS ENTROPY ETS EXPAND ETS FORECAST ETS LOAN ETS MDC ETS MODEL ETS MORTGAGE ETS PDLREG ETS SIMLIN ETS SPECTRA ETS STATESPACE ETS SYSLIN ETS TSCSREG ETS X11 ETS X12 ETS FSBROWSE FSP FSEDIT FSP FSLETTER FSP FSLIST FSP FSVIEW FSP GIS GIS ALLELE GENETICS CASECONTROL GENETICS FAMILY GENETICS HAPLOTYPE GENETICS PSMOOTH GENETICS GANNO GRAPH GAREABAR GRAPH GBARLINB GRAPH GCHART GRAPH GCONTOUR GRAPH GDEVICE GRAPH GFONT GRAPH GIMPORT GRAPH GKEYMAP GRAPH GMAP GRAPH GOPTIONS GRAPH GPLOT GRAPH GPRINT GRAPH GPROJECT GRAPH GREDUCE GRAPH GREMOVE GRAPH GREPLAY GRAPH GSLIDE GRAPH GTESTIT GRAPH G3D GRAPH G3GRID GRAPH VEDIT GRAPH IML IML MATIML IML INSIGHT INSIGHT HPF HIGH PERFORMANCE FORECASTING MDDB MDDB METAOPERATE METADATA SERVER NVISION NVISION OLAP OLAP SERVER AATRANS OR ASSIGN OR BOM OR CPM OR DTREE OR GANTT OR LP OR NETDRAW OR NETFLOW OR NLP OR PM OR TRANS OR ANOM QC CAPABILITY QC CUSUM QC FALTEX QC ISHIKAWA QC MACONTROL QC OPTEX QC PARETO QC RELIABILITY QC SHEWHART QC OPERATE SHARE SERVER SHARE G4GRID SPECTRAVIEW SPECTRAVIEW SPECTRAVIEW SVCHAR+ SPECTRAVIEW ACECLUS STAT ANOVA STAT BOXPLOT STAT CALIS STAT CANCORR STAT CANDISC STAT CATMOD STAT CLUSTER STAT CORRESP STAT DISCRIM STAT DISTANCE STAT FACTOR STAT FASTCLUS STAT GAM STAT GENMOD STAT GLM STAT GLMMOD STAT INBREED STAT KDE STAT KRIGE2D STAT LATTICE STAT LIFEREG STAT LIFETEST STAT LOESS STAT LOGISTIC STAT MDS STAT MIANALYZE STAT MI STAT MIXED STAT MODECLUS STAT MULTTEST STAT NESTED STAT NLIN STAT NLMIXED STAT NPAR1WAY STAT ORTHOREG STAT OUTPUT STAT PHREG STAT PLAN STAT PLS STAT PRINCOMP STAT PRINQUAL STAT PROBIT STAT REG STAT ROBUSTREG STAT RSREG STAT SCORE STAT SIM2D STAT STDSIZE STAT STEPDISC STAT SURVEYMEANS STAT SURVEYREG STAT SURVEYSELECT STAT TPHREG STAT TPSPLINE STAT TRANSREG STAT TREE STAT TTEST STAT VARCLUS STAT VARCOMP STAT VARIOGRAM STAT USERPROC TOOLKIT RUN; /* THIS DATA STEP PROCESSES THE SMF RECORDS DATA SET AGAINST THE */ /* SAS PROCEDURES DATA SET TO BUILD THE USAGE REPORT DATA SET */ DATA SMFREPRT(KEEP=SMFJOBN SMFPROC PROCNAME PROD); /* VALUE OF KEY VARIABLE COMES FROM THE SASSMF DATA SET */ /* AND IS USED TO FIND A MATCH ON THE INDEXED PRODUCT */ /* DATA SET. */ SET SASSMF; SET WORK.PRODUCT KEY=SMFPROC/UNIQUE; /* CHECK RETURN CODE FROM SEARCH */ SELECT (_IORC_); /* MATCH FOUND */ WHEN (%SYSRC(_SOK)) DO; OUTPUT; END; /* MATCH NOT FOUND IN MASTER */ WHEN (%SYSRC(_DSENOM)) DO; _ERROR_=0; /* RESET VALUES IN PDV FROM LAST MATCHED CONDITION */ /* IF A SAS PROCEDURE USED IS NOT FOUND ON THE */ /* PROCEDURE LIST TABLE THE PROCEDURE IS A BASE PROC */ PROD='BASE '; OUTPUT; END; OTHERWISE DO; PUT 'UNEXPECTED ERROR: _IORC_= ' _IORC_; STOP; END; END; RUN; /* USE THE USAGE REPORT DATA SET TO GENERATE A USAGE FREGUENCY REPORT */ PROC FREQ DATA=SMFREPRT; TABLES SMFJOBN * PROD / NOPERCENT NOCUM NOROW NOCOL; RUN; /* THE FOLLOWING STEPS PROVIDE AN ADDITIONAL PROC PRINT REPORT. */ /* THE FOLLOWING STEPS SORT THE USAGE REPORT DATA SET, */ /* CREATING A NEW SORTED DATA SET BY JOB NAME AND PRODUCT. */ /* THEN PRINTS AN USAGE REPORT FOR EACH JOBNAME. */ PROC SORT DATA=SMFREPRT OUT=USERSORT NODUPKEY; BY SMFJOBN PROD; RUN; DATA USERRPT(KEEP= SMFJOBN PROD); LABEL SMFJOBN='JOB NAME' PROD='PRODUCT USED'; SET USERSORT; BY SMFJOBN; IF FIRST.SMFJOBN THEN FIRST=SMFJOBN; ELSE SMFJOBN=' '; RUN; PROC PRINT DATA=USERRPT NOOBS; TITLE 'USER/JOB USING EACH PRODUCT'; RUN; /* THE FOLLOWING STEPS PROVIDE AN ADDITIONAL PROC PRINT REPORT. */ /* THE FOLLOWING STEPS SORT THE USAGE REPORT DATA SET, */ /* CREATING A NEW SORTED DATA SET BY JOB NAME AND PRODUCT. */ /* THEN PRINTS AN USAGE REPORT FOR EACH PRODUCT BY JOBNAME */ PROC SORT DATA=SMFREPRT OUT=USERSORT NODUPKEY; BY PROD SMFJOBN ; RUN; DATA USERRPT(KEEP= SMFJOBN PROD); LABEL SMFJOBN='JOB NAME' PROD='PRODUCT USED'; SET USERSORT; BY PROD; IF FIRST.PROD THEN FIRST=PROD; ELSE PROD=' '; RUN; PROC PRINT DATA=USERRPT NOOBS; VAR PROD SMFJOBN; TITLE 'PRODUCT USAGE BY USER/JOB'; RUN; @@