/* -------------------------------------------------------- */ /* private macro for reading ARM log records */ /* not for use outside of %ARMPROC macro */ /* %_ARMread(outfield,fieldfmt,inputfield); */ /* -------------------------------------------------------- */ %macro _ARMread(outfldnm, fldfmt, infldnm ); %local _ARMtype; %local _ARMint; %local _ARMicro; %let trace =*; &trace put "ARMREAD &outfldnm &fldfmt"; /* set default values */ %if &fldfmt= %then %let fldfmt = $char200.; %if &infldnm = %then %let infldnm = CharIn; %let temp = %qsubstr(&fldfmt,1,1); %if &temp = $ %then %let _ARMtype = C; %else %let _ARMtype = N; /* processing */ /* find the next comma break between fields */ _ARMpos = indexc(&infldnm, ","); &trace put _ARMpos=; if _ARMpos = 0 then do; _ARMpos = length(trim(&infldnm)) + 1; end; if _ARMpos > 1 then do; /* read the input buffer up to the comma */ %if &_ARMtype = C %then %do; /* character field */ &outfldnm = inputc((substr(&infldnm,1,_ARMpos - 1)),"&fldfmt"); %end; %else %do; /* read field initially as character, split at period */ /* integer portion is integer seconds */ /* pseudo-decimal portion is really integer to be */ /* converted to seconds by multiplying 10 to -6 power */ /* and added to integer seconds */ _ARMnum = inputc((substr(&infldnm,1,_ARMpos - 1)),"char100."); _ARMdPos = indexc(_ARMnum,"."); if _ARMdPos = 0 then _ARMdPos = length(trim(_ARMnum))+1; _ARMint = substr(_ARMnum,1,_ARMdPos - 1); _ARMicro = substr(_ARMnum,_ARMdPos + 1); *_ARMintN = input(_ARMint,32.); /* S0173544 */ _ARMintN = input(_ARMint,5.); /* S0173544 */ _ARMicroN = input(_ARMicro, ??8.); &trace put _ARMint= _ARMintN= _ARMicro= _ARMicroN=; &outfldnm = sum(input(_ARMint,32.),input(_ARMicro, ??8.)*(10**- 6)); %end; end; &trace put &outfldnm=; /* strip the input buffer of field just processed */ if (length(&infldnm) => (_ARMpos + 1)) then /* S0167260 S0167257 */ &infldnm = substr(&infldnm,_ARMpos + 1); else &infldnm = ' '; %mend; /* _ARMread */ %macro ARMPROC ( lib=WORK, log=, lognew= ); %*------------------------------------------------------------------- -*; %* Copyright (C) 1998 by SAS Institute Inc., Cary, NC 27512-8000 *; %* *; %* Name: armproc.sas *; %* Support: sasjrs - Jan Squillace *; %* Product: base *; %* Purpose: ARM Process macro - will read the ARM log file as input *; %* and write six output sas datasets containing the log *; %* information. *; %* Input: the ARM log external file *; %* Output: six SAS datasets: *; %* 1) init - contains arm_init info from log *; %* 2) getid - contains arm_getid info from log *; %* 3) start - contains arm_start info from log *; %* 4) update - contains arm_update info from log *; %* 5) stop - contains arm_stop info from log *; %* 6) end - contains arm_end info from log *; %* Parms: positional: *; %* keyword: lib - libref of output dataset. Default is *; %* WORK. *; %* *; %* log - pathname of input ARM log. No default,*; %* macro assumes the ARMLOG fileref has *; %* been pre-assigned if blank. *; %* *; %* lognew- pathname of new output ARM log. *; %* default name is "armlog.log" *; %* *; %* History: 27Mar98/tll Initial implementation *; %* 20Oct98/tll Add support for cpu time *; %* 04Sep2001/sasjrs change input for V9 ARM agent output *; %* 12Sep2001-sasjrs Add new optional parm, add code to *; %* close ARMLOG before reading *; %* 19Oct2001-sasjrs Add processing for meta-data buffers *; %* on transaction, support for ARM 2.0 *; %* API *; %* 13Dec01/jws Initial implementation *; %* Change input to allow commas in fmt2 buffers*; %* 14Jan02/jws change system and user time fields to correct*; %* format *; %* 15Apr2002- sasjrs change name elapsed time field to *; %* user CPU time. S0146921 *; %* 14Nov2002- sasjrs - pick up single character as last *; %* field on record correctly S0167257 S0167260 *; %* 08Jan2003- sasjrs - extend size of numeric fields from 5 *; %* positions to 32 S0173544 - change %ARMREAD *; %* 29Sep2006 - sasjrs - add error message for ARMLOG not assigned S0089525 *; %* *; %* *; %* *; %* Notes: - assigns the ARMLOG fileref if the log parameter is *; %* non-blank. *; %* End *; %*------------------------------------------------------------------- -*; /* close current ARMLOG, prevent ARM logging */ options armloc="_null_" ; /* signal agent to stop logging */ %let trace =*; /* for debugging, trace=* to turn off */ %local _armlog; %local _armlib; %local _armlnew; /* turn off notes and source options */ %local _ARMnote; %local _ARMsrc; %local _ARMsrc2; /* get current values to restore later */ %let _ARMnote = %sysfunc(getoption(notes)); %let _ARMsrc = %sysfunc(getoption(source)); %let _ARMsrc2 = %sysfunc(getoption(source2)); options nonotes nosource nosource2; %let _armlog = %bquote(&log); %let _armlib = %bquote(&lib); %let _armlnew = %bquote(&lognew); %if %bquote(&_armlog) eq %then %do; %if %sysfunc(fileref(ARMLOG)) ne 0 %then %do; %put %sysfunc(sysmsg()); %goto _EXTOUT; %end; %end; %else %do; %if %sysfunc(fileexist("&_armlog")) eq 0 %then %do; %put %sysfunc(sysmsg()); %goto _EXTOUT; %end; %if %sysfunc(filename(armlog,&_armlog)) ne 0 %then %do; %put %sysfunc(sysmsg()); %goto _EXTOUT; %end; %end; filename armlog "&_armlog"; data &_armlib..init (keep=appid initdt appname appuser ) &_armlib..getid (keep=clsid getiddt appid txname txdet txshdl /* value = 0, used in %armjoin */ metric1 - metric6 string1 metrDesc1 - metrDesc6 strDesc1 ) &_armlib..start (keep=txshdl startdt appid clsid parhdl parcls txusrcpu txcpu metrVal1 - metrVal6 strVal1 ) &_armlib..update(keep=txshdl updtdt appid clsid txusrcpu txcpu fmt2Buff metrVal1 - metrVal6 strVal1 ) &_armlib..stop (keep=txshdl stopdt appid clsid txstat txusrcpu txcpu metrVal1 - metrVal6 strVal1 ) &_armlib..end (keep=appid enddt appusrcpu appcpu ) ; length appid clsid txshdl 8; length logfunc $10; length appname appuser txname txdet $ 127; length fmt2Buff $ 1020; length logdt initdt getiddt startdt updtdt stopdt enddt 8; length txstat 8; length txusrcpu txcpu appusrcpu appcpu 8; length metric1 - metric6 $8 metrDesc1 - metrDesc6 $44 metrVal1 - metrVal6 $20 string1 $8 strDesc1 $44 strVal1 $32 ; label appid = 'App ID'; label clsid = 'Txn Class ID'; label txshdl = 'Start Handle'; label appname = 'App Name'; label appuser = 'App Userid'; label txname = 'Txn Name'; label txdet = 'Txn Detail'; label fmt2Buff = 'Format 2 Data'; label initdt = 'App Init Datetime'; label getiddt = 'GetID Datetime'; label startdt = 'Txn Start Datetime'; label updtdt = 'Txn Update Datetime'; label stopdt = 'Txn Stop Datetime'; label enddt = 'App End Datetime'; label txstat = 'Txn Status'; label txusrcpu = 'Txn User CPU Time'; label appusrcpu = 'App User CPU Time'; label txcpu = 'Txn System CPU Time'; label appcpu = 'App System CPU Time'; label parhdl = 'Parent Start Handle'; label parcls = 'Parent Class ID'; label fmt2Buff = 'Format 2 Data Buffer'; label metric1 = 'Metric 1 Type'; label metric2 = 'Metric 2 Type'; label metric3 = 'Metric 3 Type'; label metric4 = 'Metric 4 Type'; label metric5 = 'Metric 5 Type'; label metric6 = 'Metric 6 Type'; label metrDesc1 = 'Metric 1 Description'; label metrDesc2 = 'Metric 2 Description'; label metrDesc3 = 'Metric 3 Description'; label metrDesc4 = 'Metric 4 Description'; label metrDesc5 = 'Metric 5 Description'; label metrDesc6 = 'Metric 6 Description'; label metrVal1 = 'Metric 1 Value'; label metrVal2 = 'Metric 2 Value'; label metrVal3 = 'Metric 3 Value'; label metrVal4 = 'Metric 4 Value'; label metrVal5 = 'Metric 5 Value'; label metrVal6 = 'Metric 6 Value'; label string1 = 'String Type'; label strDesc1 = 'String Description'; label strVal1 = 'String Value'; *informat logdt 18.7; *informat initdt getiddt startdt updtdt stopdt enddt datetime23.3; format logdt initdt getiddt startdt updtdt stopdt enddt datetime23.3; format txusrcpu appusrcpu txcpu appcpu time14.6; length CharIN $328; infile armlog lrecl=328 length=LL missover; input CharIN $varying328. LL; &trace put CharIN=; %_ARMread(logfunc); %_ARMread(logdt,18.7); if logfunc = 'I' then do; %_ARMread(appid,5.); %_ARMread(time1,18.7); %_ARMread(time2,18.7); %_ARMread(appname); %_ARMread(appuser); initdt = logdt; output &_armlib..init; end; else if logfunc = 'G' then do; getiddt = logdt; %_ARMread(appid,5.); %_ARMread(clsid,5.); %_ARMread(txname); %_ARMread(txdet); %_ARMread(metrDesc1); %_ARMread(metric1); %_ARMread(metrDesc2); %_ARMread(metric2); %_ARMread(metrDesc3); %_ARMread(metric3); %_ARMread(metrDesc4); %_ARMread(metric4); %_ARMread(metrDesc5); %_ARMread(metric5); %_ARMread(metrDesc6); %_ARMread(metric6); %_ARMread(strDesc1); %_ARMread(string1); clsidCnt + 1; txshdl = 0; output &_armlib..getid; end; else if logfunc = 'C' then do; %_ARMread(appid,5.); %_ARMread(clsid,5.); %_ARMread(txshdl,5.); %_ARMread(parcls,5.); %_ARMread(parhdl,5.); %_ARMread(txusrcpu,18.7); %_ARMread(txcpu,18.7); %_ARMread(metrDesc1); %_ARMread(metric1); %_ARMread(metrDesc2); %_ARMread(metric2); %_ARMread(metrDesc3); %_ARMread(metric3); %_ARMread(metrDesc4); %_ARMread(metric4); %_ARMread(metrDesc5); %_ARMread(metric5); %_ARMread(metrDesc6); %_ARMread(metric6); %_ARMread(strDesc1); %_ARMread(string1); startdt = logdt; output &_armlib..start; end; else if logfunc = 'S' then do; %_ARMread(appid,5.); %_ARMread(clsid,5.); %_ARMread(txshdl,5.); %_ARMread(txusrcpu,18.7); %_ARMread(txcpu,18.7); %_ARMread(metrVal1); %_ARMread(metrVal2); %_ARMread(metrVal3); %_ARMread(metrVal4); %_ARMread(metrVal5); %_ARMread(metrVal6); %_ARMread(strVal1); parcls = .; parhdl = .; startdt = logdt; shdlCnt + 1; output &_armlib..start; end; else if logfunc = 'U' then do; %_ARMread(appid,5.); %_ARMread(clsid,5.); %_ARMread(txshdl,5.); %_ARMread(txusrcpu,18.7); %_ARMread(txcpu,18.7); %_ARMread(bufftype,2.); if bufftype = 0 then /* nothing more to read */ fmt2Buff = ' '; else if bufftype = 1 then do; %_ARMread(metrVal1); /* read data values */ %_ARMread(metrVal2); %_ARMread(metrVal3); %_ARMread(metrVal4); %_ARMread(metrVal5); %_ARMread(metrVal6); %_ARMread(strVal1); end; else if bufftype = 2 then fmt2Buff = charIn ; /* just take everything left */ &trace put fmt2Buff=; updtdt = logdt; updtCnt + 1; output &_armlib..update; end; else if logfunc = 'P' then do; %_ARMread(appid,5.); %_ARMread(clsid,5.); %_ARMread(txshdl,5.); %_ARMread(txusrcpu,18.7); %_ARMread(txcpu,18.7); %_ARMread(txstat,5.); %_ARMread(metrVal1); %_ARMread(metrVal2); %_ARMread(metrVal3); %_ARMread(metrVal4); %_ARMread(metrVal5); %_ARMread(metrVal6); %_ARMread(strVal1); stopdt = logdt; output &_armlib..stop; end; else if logfunc = 'E' then do; %_ARMread(appid,5.); %_ARMread(appusrcpu,18.7); %_ARMread(appcpu,18.7); enddt = logdt; output &_armlib..end; end; run; %if %bquote(&_armlog) ne %then %do; filename armlog clear; %end; options armloc="&_armlnew"; /* reset ARM Logging */ %goto _EXTOUT; %_ERROUT: %put ERROR: Invalid log= parameter. Must be a valid path name.; %_EXTOUT: /* restore existing options before exit */ options &_ARMnote &_ARMsrc &_ARMsrc2; %mend; /* armproc */