! This contains a repeat of the accouting processing definitions, ! with some modifications and extra procedures for measuring system ! terminal usage in Erlangs, from which blocking may be calculated. ! It was originally done (rather quickly) for the DECUServe system, ! but would be useful for any system where people access a system ! through dial-up lines, port selectors, etc. and compete for a ! limited number of ports. See INSTRUCTIONS.RNO ! ! B. Z. Lederman ! ITT World Communications ! 67 Broad St. 28th Floor ! New York, NY 10004-2464 DELETE ACC; REDEFINE DOMAIN ACC USING ACC_RECORD ON DSK7:[ACCOUNTING]ACCFIX.18SEP; DELETE ACC_RECORD; REDEFINE RECORD ACC_RECORD OPTIMIZE 01 ACC_REC. ! ! This record definition reads the fields produced by the ! program which "fixes" System Accounting records by putting them ! into fixed format fields. ! ! B. Z. Lederman 15-Apr-1987 ! 05 ROOT. 10 TYPE USAGE BYTE. 10 SUB_TYPE USAGE BYTE. 10 SYSTEM_DATE USAGE DATE. 10 EBIN REDEFINES SYSTEM_DATE. ! used for elapsed time 20 EQUAD USAGE QUAD. ! computations 05 INFO. 10 PACKET COMPUTED BY SUB_TYPE VIA ACC_SUBTYPE_TABLE. 10 SYSTEM_TIME COMPUTED BY FN$TIME(SYSTEM_DATE) EDIT_STRING X(12). ! ! Begin fields from ID packet ! 05 ID. 10 IDENT. 20 DIN. 30 FILLER PIC X(20). 20 DECIMALS REDEFINES DIN. 30 DPID USAGE LONG. ! process ID 30 DPIDOWN USAGE LONG. ! Owner process ID 30 DUIC USAGE LONG. 30 DPRIV1 USAGE LONG. 30 DPRIV2 USAGE LONG. 20 PID COMPUTED BY FN$HEX(DPID) EDIT_STRING X(8). 20 PIDOWN COMPUTED BY FN$HEX(DPIDOWN) EDIT_STRING X(8). ! ! The next two fields require a user-defined function supplied ! on the DTR/4GL SIG Library Collection (also found on the VAX SIG Tapes. ! It formats the binary UIC into meaningful information. ! 20 NUIC COMPUTED BY FN$FAO("!%I",DUIC,"","","","","","","") EDIT_STRING X(14). 20 OUIC COMPUTED BY FN$FAO("!%U",DUIC,"","","","","","","") EDIT_STRING X(9). 20 PRIVILEGES. 30 PRIV1 COMPUTED BY FN$HEX(DPRIV1) EDIT_STRING X(8). 30 PRIV2 COMPUTED BY FN$HEX(DPRIV2) EDIT_STRING X(8). 20 PRIORITY USAGE BYTE EDIT_STRING Z9. 10 USER. 20 USERNAME PIC X(12). 20 ACCOUNT PIC X(8). 20 NODE PIC X(6). 20 TERMINAL PIC X(6). 10 JOB. 20 JOBNAME PIC X(12). 20 JOBID USAGE LONG EDIT_STRING ZZ,ZZ9. 20 QUEUE PIC X(32) EDIT_STRING T(16). 20 NODEADDR USAGE WORD EDIT_STRING ZZ,ZZ9. 20 REMOTE_ID PIC X(16). ! ! Start process deletion fields ! 05 PROCESS_DELETION. 10 TIMES. 20 SD. ! used to "hide" the starting date 30 FILLER PIC X(8). ! because we don't need two dates 20 SDATE REDEFINES SD. 30 START_DATE USAGE DATE. 30 SBIN REDEFINES START_DATE. 40 SQUAD USAGE QUAD. 20 START_TIME COMPUTED BY FN$TIME(START_DATE) EDIT_STRING X(12). ! ! Compute the elapsed connect time in seconds. ! 20 ELAPSED COMPUTED BY (EQUAD - SQUAD) / 10000000 EDIT_STRING ZZ,ZZ9.99. 10 STATUS. 20 FSTAT. 30 FILLER PIC XXXX. 20 RSTAT REDEFINES FSTAT. 30 DSTAT USAGE LONG. 30 HSTAT COMPUTED BY FN$HEX(DSTAT) EDIT_STRING X(8). ! ! The following field requires a user-define function (see FN$FAO). ! It converts the exit status from a number into a system message. ! 20 STATUS_TEXT COMPUTED BY FN$GETMSG(DSTAT,0) EDIT_STRING T(32). 10 COUNTS. 20 IMAGE_COUNT USAGE LONG. 20 CPU_TIME USAGE LONG PIC 9(10)V99 EDIT_STRING Z,ZZZ,ZZZ,ZZ9.99. 20 FAULTS USAGE LONG EDIT_STRING Z,ZZZ,ZZ9. 20 FAULT_IO USAGE LONG EDIT_STRING Z,ZZZ,ZZ9. 20 WS_PEAK USAGE LONG. 20 PAGE_FILE USAGE LONG EDIT_STRING Z,ZZZ,ZZ9. 20 DIO_COUNT USAGE LONG EDIT_STRING Z,ZZZ,ZZ9. 20 BIO_COUNT USAGE LONG EDIT_STRING Z,ZZZ,ZZ9. 20 VOLUMES USAGE LONG. ! ! The following is needed for calculating Erlang traffic ! figures by each minute of the day. ! 10 MOD. ! Minute of Day (0 to 1439) 20 START_MOD COMPUTED BY (FN$HOUR(START_DATE) * 60) + FN$MINUTE(START_DATE) EDIT_STRING ZZZ9. 20 END_MOD COMPUTED BY (FN$HOUR(SYSTEM_DATE) * 60) + FN$MINUTE(SYSTEM_DATE) EDIT_STRING ZZZ9. ; DELETE ACC_SUBTYPE_TABLE; REDEFINE TABLE ACC_SUBTYPE_TABLE 33 : "Interactive", 34 : "Subprocess", 35 : "Detached", 36 : "Batch", 37 : "Network" ELSE "Undefined" END_TABLE DELETE FIRST_CALCULATE; REDEFINE PROCEDURE FIRST_CALCULATE ! ! Calculate traffic statistics from Accounting Records. ! ! This procedure marks the minutes of the day when a terminal line ! was in use. There is a little error because it doesn't consider ! that a line might have been used for only part of a minute, but ! the actual error is small (and a lot of extra calculations are ! needed to get the partial minutes). By doing it this way we ! Also get a count of how many users there were on the system ! at any given moment (not of much use, but some people like ! to look at it). ! ! B. Z. Lederman 11-Sep-1987 ! READY ACC DECLARE SMOD USAGE INTEGER. ! ! We have to clear out any old data: this can be slow. ! !READY MOD MODIFY !FOR MOD MODIFY USING BEGIN ! TIME_BUSY = 0 ! NUMBER_BUSY = 0 !END ! ! If FN$DCL is available, there is a much faster way to create an empty file. ! FINISH MOD FN$DCL("CONVERT/FDL=MOD MOD.SEQ MOD.DOM") FN$DCL("PURGE/NOLOG MOD.DOM") READY MOD MODIFY ! ! Read the accounting data (use only those records that are relevant: ! in this case, only "real" terminals, not DECnet remote terminals, ! and not Batch jobs, etc. ! FOR ACC WITH TERMINAL STARTING "VT" BEGIN ! ! Get the time the session started. ! SMOD = START_MOD ! ! For each minute this session was busy, add 1 minute of use. ! WHILE SMOD LE END_MOD BEGIN FOR MOD WITH M_OF_D = SMOD MODIFY USING BEGIN TIME_BUSY = TIME_BUSY + 1 NUMBER_BUSY = NUMBER_BUSY + 1 END SMOD = SMOD + 1 END END END-PROCEDURE DELETE HOURLY; REDEFINE DOMAIN HOURLY USING HOURLY_RECORD ON USER$DEVICE:[LEDERMAN.ACCOUNTING]HOURLY.DOM; DELETE HOURLY_RECORD; REDEFINE RECORD HOURLY_RECORD OPTIMIZE 01 HOURLY_REC. ! ! Holds statistics for each hour of the day (generally obtained ! by summarizing MOD). ! ! B. Z. Lederman 21-Sep-1987 ! 10 HOUR USAGE INTEGER EDIT_STRING Z9 QUERY_HEADER "Hour"/"of"/"Day". 10 NUMBER_BUSY USAGE INTEGER EDIT_STRING Z,ZZ9 QUERY_HEADER "Maximum"/"Number"/"of"/"Users". 10 ERLANGS USAGE REAL EDIT_STRING Z,ZZ9.99 QUERY_HEADER "Erlangs". ; DELETE HOURLY_REPORT; REDEFINE PROCEDURE HOURLY_REPORT ! ! Report the Traffix during each clock hour. ! ! B. Z. Lederman 21-Sep-1987 ! READY HOURLY REPORT HOURLY ON *."TT or file name" SET REPORT_NAME = "Hourly Traffic Measurements" PRINT HOUR, SPACE 2, ERLANGS, SPACE 2, NUMBER_BUSY END_REPORT END-PROCEDURE DELETE HOURLY_SEQ; REDEFINE DOMAIN HOURLY_SEQ USING HOURLY_RECORD ON USER$DEVICE:[LEDERMAN.ACCOUNTING]HOURLY.SEQ; DELETE INITIALIZE_HOURLY; REDEFINE PROCEDURE INITIALIZE_HOURLY ! ! Create a new Minute-of-Day summary file for processing traffic data. ! This should not be needed very often. ! ! B. Z. Lederman 21-Sep-1987 ! DEFINE FILE FOR HOURLY_SEQ; ! remember to purge old files ! READY HOURLY_SEQ WRITE DECLARE T_HOUR USAGE INTEGER. T_HOUR = 0 ! ! Make one record for each hour of the day, sequentially numbered. ! WHILE T_HOUR LE 23 BEGIN STORE HOURLY_SEQ USING BEGIN HOUR = T_HOUR ERLANGS = 0 NUMBER_BUSY = 0 END T_HOUR = T_HOUR + 1 END END-PROCEDURE DELETE INITIALIZE_MOD; REDEFINE PROCEDURE INITIALIZE_MOD ! ! Create a new Minute-of-Day file for processing traffic data. ! This should not be needed very often. ! ! B. Z. Lederman 11-Sep-1987 ! DEFINE FILE FOR MOD_SEQ ALLOCATION=20; ! remember to purge old files ! READY MOD_SEQ WRITE DECLARE MINUTE USAGE INTEGER. DECLARE HOUR USAGE INTEGER. DECLARE HOUR_COUNTER USAGE INTEGER. MINUTE = 0 HOUR = 0 HOUR_COUNTER = 0 ! ! Make one record for each minute of the day, sequentially numbered. ! WHILE MINUTE LE 1439 BEGIN STORE MOD_SEQ USING BEGIN M_OF_D = MINUTE H_OF_D = HOUR TIME_BUSY = 0 NUMBER_BUSY = 0 END MINUTE = MINUTE + 1 HOUR_COUNTER = HOUR_COUNTER + 1 ! ! Also mark the hour of the day for summarizing. ! IF HOUR_COUNTER = 60 THEN BEGIN HOUR = HOUR + 1 HOUR_COUNTER = 0 END END END-PROCEDURE DELETE INITIALIZE_MOD_SUM; REDEFINE PROCEDURE INITIALIZE_MOD_SUM ! ! Create a new Minute-of-Day summary file for processing traffic data. ! This should not be needed very often. ! ! B. Z. Lederman 21-Sep-1987 ! DEFINE FILE FOR MOD_SUM_SEQ ALLOCATION=20; ! remember to purge old files ! READY MOD_SUM_SEQ WRITE DECLARE T_HOUR USAGE INTEGER. T_HOUR = 0 ! ! Make one record for each minute of the day, sequentially numbered. ! WHILE T_HOUR LE 23 BEGIN STORE MOD_SUM_SEQ USING BEGIN HOUR = T_HOUR ERLANGS = 0 NUMBER_BUSY = 0 END T_HOUR = T_HOUR + 1 END END-PROCEDURE DELETE MOD; REDEFINE DOMAIN MOD USING MOD_RECORD ON USER$DEVICE:[LEDERMAN.ACCOUNTING]MOD.DOM; DELETE MOD_ERLANG_REPORT; REDEFINE PROCEDURE MOD_ERLANG_REPORT ! ! Totalize the amount of time busy during each clock hour, and ! report. ! ! B. Z. Lederman 11-Sep-1987 ! READY MOD REPORT MOD ON *."TT or file name" SET REPORT_NAME = "Hourly Traffic Summary" AT BOTTOM OF H_OF_D PRINT H_OF_D("Hour"), SPACE 2, FORMAT(TOTAL(TIME_BUSY) / 60) USING Z,ZZ9.99 ("Erlangs"), SPACE 2, MAX(NUMBER_BUSY) ("Maximum"/"Number"/"of"/"Users") END_REPORT END-PROCEDURE DELETE MOD_RECORD; REDEFINE RECORD MOD_RECORD OPTIMIZE 01 MOD_REC. ! ! Define one record for each minute of the day for processing ! traffic data. ! ! B. Z. Lederman 11-Sep-1987 ! 10 M_OF_D USAGE INTEGER EDIT_STRING ZZZ9 QUERY_HEADER "Minute"/"of"/"Day". 10 H_OF_D USAGE INTEGER EDIT_STRING Z9 QUERY_HEADER "Hour"/"of"/"Day". 10 NUMBER_BUSY USAGE INTEGER EDIT_STRING Z,ZZ9. 10 TIME_BUSY USAGE REAL EDIT_STRING Z,ZZ9.99. ; DELETE MOD_SEQ; REDEFINE DOMAIN MOD_SEQ USING MOD_RECORD ON USER$DEVICE:[LEDERMAN.ACCOUNTING]MOD.SEQ; DELETE PSI; REDEFINE DOMAIN PSI USING PSI_RECORD ON DSK7:[ACCOUNTING]PSIACCFIX.18SEP; DELETE PSI_RECORD; REDEFINE RECORD PSI_RECORD OPTIMIZE 01 PSI_REC. ! ! This record definition reads the fields produced by the ! program which "fixes" PSI accounting records by putting them ! into fixed format fields. ! ! B. Z. Lederman 14-Apr-1987 ! 05 ROOT. 10 TYPE USAGE BYTE. 10 SUB_TYPE USAGE BYTE. 10 SYSTEM_DATE USAGE DATE. 10 EBIN REDEFINES SYSTEM_DATE. ! used for elapsed time 20 EQUAD USAGE QUAD. ! computations 05 INFO. 10 PACKED COMPUTED BY SUB_TYPE VIA ACC_SUBTYPE_TABLE. 10 SYSTEM_TIME COMPUTED BY FN$TIME(SYSTEM_DATE) EDIT_STRING X(12). ! ! Begin fields from ID packet ! 05 ID. 10 IDENT. 20 DIN. 30 FILLER PIC X(20). 20 DECIMALS REDEFINES DIN. 30 DPID USAGE LONG. ! process ID 30 DPIDOWN USAGE LONG. ! Owner process ID 30 DUIC USAGE LONG. 30 DPRIV1 USAGE LONG. 30 DPRIV2 USAGE LONG. 20 PID COMPUTED BY FN$HEX(DPID) EDIT_STRING X(8). 20 PIDOWN COMPUTED BY FN$HEX(DPIDOWN) EDIT_STRING X(8). ! ! The next two fields require a user-defined function supplied ! on the DTR/4GL SIG Library Collection (also found on the VAX SIG Tapes. ! It formats the binary UIC into meaningful information. ! 20 NUIC COMPUTED BY FN$FAO("!%I",DUIC,"","","","","","","") EDIT_STRING X(14). 20 PRIVILEGES. 30 PRIV1 COMPUTED BY FN$HEX(DPRIV1) EDIT_STRING X(8). 30 PRIV2 COMPUTED BY FN$HEX(DPRIV2) EDIT_STRING X(8). 20 PRIORITY USAGE BYTE EDIT_STRING Z9. 10 USER. 20 USERNAME PIC X(12). 20 ACCOUNT PIC X(8). 20 NODE PIC X(6). 20 TERMINAL PIC X(6). 10 UNUSED1. 20 FILLER PIC X(66). 10 JOB REDEFINES UNUSED1. ! most of this isn't used by PSI 20 JOBNAME PIC X(12). ! accounting, which is unfortunate 20 JOBID USAGE LONG. 20 QUEUE PIC X(32). 20 NODEADDR USAGE WORD. 20 REMOTE_ID PIC X(16). ! ! Start PSI (termination) fields ! 05 PROCESS_DELETION. 10 TIMES. 20 SD. ! used to "hide" the starting date 30 FILLER PIC X(8). ! because we don't need two dates 20 SDATE REDEFINES SD. ! and it isn't always filled in. 30 START_DATE USAGE DATE. 30 SBIN REDEFINES START_DATE. 40 SQUAD USAGE QUAD. 20 START_TIME COMPUTED BY FN$TIME(START_DATE) EDIT_STRING X(12). ! ! Calculate the elapsed connect time in seconds. Isn't always correct ! because PSI doens't always fill in all of the fields. ! 20 ELAPSED COMPUTED BY CHOICE OF ! elapsed time in seconds (SQUAD NE 0) THEN ((EQUAD - SQUAD) / 10000000) ELSE 0.0 END_CHOICE EDIT_STRING ZZZ,ZZZ.999. 10 DEST. 20 DESTINATION PIC X(32). 20 REMOTE_DTE PIC X(14). 20 LOCAL_DTE PIC X(14). 20 NETWORK PIC X(16). 10 CHAN. 20 FILLER PIC X(8). 10 CHANS REDEFINES CHAN. 20 PVC PIC X(6). 20 DLCN USAGE WORD EDIT_STRING ZZ9. ! Logical Channel Number (decimal) 10 LCN COMPUTED BY FN$HEX(DLCN) EDIT_STRING X(8). ! more normally seen like this. 10 STATS. 20 B_OUT USAGE LONG EDIT_STRING ZZZ,ZZ9. ! Bytes 20 B_IN USAGE LONG EDIT_STRING ZZZ,ZZ9. 20 S_OUT USAGE LONG EDIT_STRING Z,ZZ9. ! Segments 20 S_IN USAGE LONG EDIT_STRING Z,ZZ9. 20 P_OUT USAGE LONG EDIT_STRING Z,ZZ9. ! Packets 20 P_IN USAGE LONG EDIT_STRING Z,ZZ9. 20 M_OUT USAGE LONG EDIT_STRING Z,ZZ9. ! Messages 20 M_IN USAGE LONG EDIT_STRING Z,ZZ9. 10 INPUT_FIELDS1. 20 FILLER PIC X(14). 10 DECIMAL_FIELDS1 REDEFINES INPUT_FIELDS1. ! read as decimal, 20 DTHR_IN USAGE WORD. ! but usually referred to as Hex. 20 DTHR_OUT USAGE WORD. 20 DWINDOW_IN USAGE WORD. 20 DWINDOW_OUT USAGE WORD. 20 DPACKET_IN USAGE WORD. 20 DPACKET_OUT USAGE WORD. 20 DCUG USAGE WORD. ! Closed User Group 10 NEGOTIATION. 20 THR_IN COMPUTED BY FN$HEX(DTHR_IN) EDIT_STRING X(8). 20 THR_OUT COMPUTED BY FN$HEX(DTHR_OUT) EDIT_STRING X(8). 20 WINDOW_IN COMPUTED BY FN$HEX(DWINDOW_IN) EDIT_STRING X(8). 20 WINDOW_OUT COMPUTED BY FN$HEX(DWINDOW_OUT) EDIT_STRING X(8). 20 PACKET_IN COMPUTED BY FN$HEX(DPACKET_IN) EDIT_STRING X(8). 20 PACKET_OUT COMPUTED BY FN$HEX(DPACKET_OUT) EDIT_STRING X(8). 20 CUG COMPUTED BY FN$HEX(DCUG) EDIT_STRING X(8). 10 FACILITIES. 20 REQUESTED USAGE WORD EDIT_STRING ZZZ9. 20 CLEARING PIC X(16). 20 CALLING PIC X(16). 20 ACCEPTING PIC X(16). 10 INPUT_FIELDS2. 20 FILLER PIC XXX. 10 DECIMAL_FIELDS2 REDEFINES INPUT_FIELDS2. 20 DREASON USAGE BYTE. 20 DCAUSE USAGE BYTE. 20 DDIAG USAGE BYTE. 10 TERMINATION. 20 REASON COMPUTED BY FN$HEX(DREASON) EDIT_STRING X(8). 20 CAUSE COMPUTED BY FN$HEX(DCAUSE) EDIT_STRING X(8). 20 DIAGNOSTIC COMPUTED BY FN$HEX(DDIAG) EDIT_STRING X(8). 10 UNIT PIC X(6). ! NV or NW unit used 10 PROTOCOL PIC X(4). ; DELETE HOURLY_SUM; REDEFINE PROCEDURE HOURLY_SUM; ! ! Summarize traffic statistics from Accounting Records. ! ! This procedure sums the hourly statistics from the Minute-of-Day stats. ! ! B. Z. Lederman 21-Sep-1987 ! READY MOD ! ! We have to clear out any old data: this can be slow. ! !READY HOURLY MODIFY !FOR HOURLY MODIFY USING BEGIN ! ERLANGS = 0 ! NUMBER_BUSY = 0 !END ! ! If FN$DCL is available, there is a much faster way to create an empty file. ! FINISH HOURLY FN$DCL("CONVERT/FDL=HOURLY HOURLY.SEQ HOURLY.DOM") FN$DCL("PURGE/NOLOG HOURLY.DOM") READY HOURLY MODIFY ! ! Read the MOD (Minute of Day) data and reduce to hourly totals. ! ! Process only those records which have some data. ! FOR MOD WITH TIME_BUSY > 0 BEGIN ! ! Total up holding time, and get maximum value for number busy. ! FOR HOURLY WITH HOUR = H_OF_D MODIFY USING BEGIN ERLANGS = ERLANGS + TIME_BUSY IF MOD_REC.NUMBER_BUSY > HOURLY_REC.NUMBER_BUSY THEN HOURLY_REC.NUMBER_BUSY = MOD_REC.NUMBER_BUSY END END ! ! Convert minutes to Erlangs ! FOR HOURLY MODIFY USING ERLANGS = ERLANGS / 60.0 END-PROCEDURE DELETE T132; REDEFINE PROCEDURE T132 SET COLUMNS_PAGE=132 FN$WIDTH(132) ![?3h END-PROCEDURE DELETE T80; REDEFINE PROCEDURE T80 SET COLUMNS_PAGE=80 FN$WIDTH(80) ![?3l END-PROCEDURE