#!/usr/local/bin/rxx /* daily.usage.summary (c) copyright 1995, Paul Zarnowski and Cornell University (see "Legal Information", below) This exec reads the ADSM accounting file and writes summary information to standard output. Syntax: daily.usage.data Where: specifies the filename of the ADSM Accounting File. are any of the following: - indicates to summarize for days ago. -d indicates to summarize for specified date. must have the format mm/dd/yyyy -m indicates to summarize for the entire month which includes the date specified by - and -d . Author Info: Paul Zarnowski (psz1@cornell.edu) 315 CCC Cornell Information Technologies Ithaca, NY 14853-2601 Update History: 19-Oct-94 PSZ Initial version created */ /* Initialization */ G. = 0 G.$DEBUG = 0 G.$TOPN = 10 G.$DATE = "" G.$DATEOFFSET = 0 G.$NODES = "" G.$KB = 0 G.$BKPKB = 0 G.$RSTKB = 0 G.$ARCKB = 0 G.$RETKB = 0 G.$BKPOBJ = 0 G.$RSTOBJ = 0 G.$ARCOBJ = 0 G.$RETOBJ = 0 G.$SESSIONS = 0 G.$SECONDS = 0 G.$ABNORMAL = 0 G.$IDLEWAIT = 0 G.$COMMWAIT = 0 G.$MEDIAWAIT = 0 G.$BKPSESS = 0 G.$RSTSESS = 0 G.$ARCSESS = 0 G.$RETSESS = 0 KB. = 0 /* Syntax */ parse arg fn options G.$FN = fn oo = options do while (oo <> "") parse value oo with o oo select when (o = "-m") then G.$SELMONTH = 1 when (o = "-d") then do parse value oo with G.$DATE oo end when (datatype(o,"W")) then do G.$DATEOFFSET = o end otherwise do say "Invalid option," o exit 12 end end end G.$SUMDATE = edate(U,G.$DATE,G.$DATEOFFSET,L) if (G.$SELMONTH) then do G.$SUMMONTH = month(G.$SUMDATE) G.$PERIOD = "month of" G.$SUMMONTH end else do G.$PERIOD = G.$SUMDATE end /* Process all of standard input */ O. = 0; O.$NODES = "" CDate = 0 do while (lines(G.$FN) > 0) l = linein(G.$FN) parse value l with ProdLevel "," , ProdSublevel "," , ProdName "," , ADate "," , ATime "," , Node "," , Owner "," , Platform "," , AuthMethod "," , CommMethod "," , TermInd "," , ArchObjs "," , ArchKB "," , RetrObjs "," , RetrKB "," , BackObjs "," , BackKB "," , RestObjs "," , RestKB "," , KB "," , TotalSeconds "," , IdleWaitSeconds "," , CommWaitSeconds "," , MediaWaitSeconds if (G.$SELMONTH) then do if (month(ADate) <> G.$SUMMONTH) then iterate end else do if (G.$SUMDATE <> ADate) then iterate end G.$KB = G.$KB + KB G.$BKPKB = G.$BKPKB + BackKB G.$RSTKB = G.$RSTKB + RestKB G.$ARCKB = G.$ARCKB + ArchKB G.$RETKB = G.$RETKB + RetrKB G.$BKPOBJ = G.$BKPOBJ + BackObjs G.$RSTOBJ = G.$RSTOBJ + RestObjs G.$ARCOBJ = G.$ARCOBJ + ArchObjs G.$RETOBJ = G.$RETOBJ + RetrObjs if (BackObjs > 0) then do G.$BKPSESS = G.$BKPSESS + 1 G.$BKPSECS = G.$BKPSECS + TotalSeconds G.$BKPIDLE = G.$BKPIDLE + IdleWaitSeconds G.$BKPCOMM = G.$BKPCOMM + CommWaitSeconds G.$BKPMEDIA = G.$BKPMEDIA + MediaWaitSeconds end if (RestObjs > 0) then do G.$RSTSESS = G.$RSTSESS + 1 G.$RSTSECS = G.$RSTSECS + TotalSeconds G.$RSTIDLE = G.$RSTIDLE + IdleWaitSeconds G.$RSTCOMM = G.$RSTCOMM + CommWaitSeconds G.$RSTMEDIA = G.$RSTMEDIA + MediaWaitSeconds end if (ArchObjs > 0) then do G.$ARCSESS = G.$ARCSESS + 1 G.$ARCSECS = G.$ARCSECS + TotalSeconds G.$ARCIDLE = G.$ARCIDLE + IdleWaitSeconds G.$ARCCOMM = G.$ARCCOMM + CommWaitSeconds G.$ARCMEDIA = G.$ARCMEDIA + MediaWaitSeconds end if (RetrObjs > 0) then do G.$RETSESS = G.$RETSESS + 1 G.$RETSECS = G.$RETSECS + TotalSeconds G.$RETIDLE = G.$RETIDLE + IdleWaitSeconds G.$RETCOMM = G.$RETCOMM + CommWaitSeconds G.$RETMEDIA = G.$RETMEDIA + MediaWaitSeconds end if (BackObjs = 0) & (RestObjs = 0) & (ArchObjs = 0) & (RetrObjs = 0) then do G.$ADMSESS = G.$ADMSESS + 1 G.$ADMSECS = G.$ADMSECS + TotalSeconds G.$ADMIDLE = G.$ADMIDLE + IdleWaitSeconds G.$ADMCOMM = G.$ADMCOMM + CommWaitSeconds G.$ADMMEDIA = G.$ADMMEDIA + MediaWaitSeconds G.$ADMKB = G.$ADMKB + KB end if (TermInd = '00'x) then G.$ABNORMAL = G.$ABNORMAL + 1 G.$SESSIONS = G.$SESSIONS + 1 G.$SECONDS = G.$SECONDS + TotalSeconds G.$IDLEWAIT = G.$IDLEWAIT + IdleWaitSeconds G.$COMMWAIT = G.$COMMWAIT + CommWaitSeconds G.$MEDIAWAIT = G.$MEDIAWAIT + MediaWaitSeconds KB.Node = KB.Node + KB if (wordpos(Node,G.$NODES) = 0) then G.$NODES = G.$NODES Node end /* Write summary data */ call summarize /* Append footnotes */ call footnotes /* Append stats on Top Users */ call topten /* Exit */ exit summarize: procedure expose G. KB. call output("ADSM Activity Report for" G.$PERIOD) call output(" ") l = "Activity # Sess # Obj # Bytes Time MediaW CommW IdleW Xfer Rate"; call output(l) l = "------------ ------ ------ ------- ---------- ------ ------ ------ ------------"; call output(l) l = "------------ 123.4x 123.4x 123.4xB hhhh:mm:ss -nn.n% -nn.n% -nn.n% nnnn.nn KB/s" l = "Backup " , fmtkmg(G.$BKPSESS) , fmtkmg(G.$BKPOBJ) , fmtkmg(1000*G.$BKPKB)"B" , fmttime(G.$BKPSECS) , fmtpct(G.$BKPMEDIA G.$BKPSECS) , fmtpct(G.$BKPCOMM G.$BKPSECS) , fmtpct(G.$BKPIDLE G.$BKPSECS) , fmtkbs(G.$BKPKB G.$BKPSECS-(G.$BKPMEDIA+G.$BKPIDLE)); call output(l) l = "Restore " , fmtkmg(G.$RSTSESS) , fmtkmg(G.$RSTOBJ) , fmtkmg(1000*G.$RSTKB)"B" , fmttime(G.$RSTSECS) , fmtpct(G.$RSTMEDIA G.$RSTSECS) , fmtpct(G.$RSTCOMM G.$RSTSECS) , fmtpct(G.$RSTIDLE G.$RSTSECS) , fmtkbs(G.$RSTKB G.$RSTSECS-(G.$RSTMEDIA+G.$RSTIDLE)); call output(l) l = "Archive " , fmtkmg(G.$ARCSESS) , fmtkmg(G.$ARCOBJ) , fmtkmg(1000*G.$ARCKB)"B" , fmttime(G.$ARCSECS) , fmtpct(G.$ARCMEDIA G.$ARCSECS) , fmtpct(G.$ARCCOMM G.$ARCSECS) , fmtpct(G.$ARCIDLE G.$ARCSECS) , fmtkbs(G.$ARCKB G.$ARCSECS-(G.$ARCMEDIA+G.$ARCIDLE)); call output(l) l = "Retrieve " , fmtkmg(G.$RETSESS) , fmtkmg(G.$RETOBJ) , fmtkmg(1000*G.$RETKB)"B" , fmttime(G.$RETSECS) , fmtpct(G.$RETMEDIA G.$RETSECS) , fmtpct(G.$RETCOMM G.$RETSECS) , fmtpct(G.$RETIDLE G.$RETSECS) , fmtkbs(G.$RETKB G.$RETSECS-(G.$RETMEDIA+G.$RETIDLE)); call output(l) l = "Other " , fmtkmg(G.$ADMSESS) , fmtkmg(0) , fmtkmg(1000*G.$ADMKB)"B" , fmttime(G.$ADMSECS) , fmtpct(G.$ADMMEDIA G.$ADMSECS) , fmtpct(G.$ADMCOMM G.$ADMSECS) , fmtpct(G.$ADMIDLE G.$ADMSECS) , fmtkbs(G.$ADMKB G.$ADMSECS-(G.$ADMMEDIA+G.$ADMIDLE)); call output(l) totobjs = G.$BKPOBJ + G.$RSTOBJ + G.$ARCOBJ + G.$RETOBJ l = "Total " , fmtkmg(G.$SESSIONS) , fmtkmg(totobjs) , fmtkmg(1000*G.$KB)"B" , fmttime(G.$SECONDS) , fmtpct(G.$MEDIAWAIT G.$SECONDS) , fmtpct(G.$COMMWAIT G.$SECONDS) , fmtpct(G.$IDLEWAIT G.$SECONDS) , fmtkbs(G.$KB G.$SECONDS-(G.$MEDIAWAIT+G.$IDLEWAIT)); call output(l) return footnotes: procedure expose G. call output(" ") call output("Notes:") call output(" - Time = total wall-clock time") call output(" - MediaW = % of wall-clock time spent waiting for Media") call output(" - CommW = % of wall-clock time spent waiting for Network") call output(" - IdleW = % of wall-clock time spent idle (waiting for user)") call output(" - Xfer Rate = Transfer Rate (Bytes / (Time * (1 - (MediaW + IdleW))))") return output: procedure expose G. parse arg line say line return 0 topten: procedure expose G. KB. parse source with . . . progname . /* pid = _getpid() */ pid = 0 tempfile = "/tmp/"progname"."pid".tmp" totalnodes = 0 totalKB = 0 nn = G.$NODES do while (nn <> "") parse value nn with n nn totalnodes = totalnodes + 1 totalKB = totalKB + KB.n l = format(KB.n,10) n call lineout tempfile, l end call lineout tempfile cmd = "/bin/sort -r" tempfile "| /bin/head -"G.$TOPN q = queued() call popen(cmd) if (queued() > q) then do call output(" ") call output("# Bytes % Tot Top" G.$TOPN "nodes for" G.$PERIOD":") call output("------- ------ ----------------------------------------") end do while (queued() > q) parse pull kb node l = fmtkmg(kb*1000)||"B" fmtpct(kb totalkb) node; call output(l) end avgkb = totalkb / totalnodes l = fmtkmg(avgkb*1000)||"B" "Average, for" totalnodes "nodes." call output(l) '/bin/rm' tempfile return /* fmttime: return "hhhh:mm:ss" */ fmttime: procedure parse arg seconds . hhhh=0; mm=0; ss=0 mm = seconds % 60 ss = seconds - (60 * mm) hhhh = mm % 60 mm = mm - (60 * hhhh) return format(hhhh,4)":"right(mm,2,"0")":"right(ss,2,"0") /* fmtpct: return " nn.n%" */ fmtpct: procedure parse arg part total . select when (total = 0) then pct = "" when (part = 0) then pct = "0" when (part > total) then pct = "***.*" when (part/total < 0.001) then pct = format(100*(part/total),1,3) otherwise pct = format(100*(part/total),3,1) end if (pct = "") then return right(pct,5)||" " else return right(pct,5)||"%" /* fmtkbs: return "nnnn.nn KB/s" */ fmtkbs: procedure parse arg kbytes seconds . select when (seconds = 0) then rate = 0 otherwise rate = format(kbytes/seconds,4,2) end if (rate = 0) then return " " else return right(rate,7)" KB/s" /* fmtcomma: return "nnn,nnn,nn0" */ /* Not Finished */ fmtcomma: procedure parse arg number . return number /* fmtkmg: return "nnn.nX" (X = K or M or G) */ fmtkmg: procedure parse arg number . select when (number < 100000) then do n = number return right(format(n,5,0),5)||" " end when (number < 1000000) then do n = number / 1000 return right(format(n,3,1),5)||"K" end when (number < 1000000000) then do n = number / 1000000 return right(format(n,3,1),5)||"M" end when (number < 1000000000000) then do n = number / 1000000000 return right(format(n,3,1),5)||"G" end otherwise return "***.*?" end return "ERROR " month: procedure parse arg datestring parse value datestring with mm '/' dd '/' yyyy return mm"/"yyyy /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* Legal Information: Although copyrighted, this software is being licensed to you for your use free of charge. However, ownership of and interest in this software shall remain with the author. Use and distribution of this software is governed by the following terms. This software is owned by the author and contains valuable and proprietary information of the author. If you violate any part of this agreement, your right to use this software terminates automatically. In the event of termination of this agreement, you must destroy all copies of this software and derivatives of this software in your possession and cease distributing the same. This software is being licensed to you as provided by the terms of this agreement. You may: 1. Use this software on as many computers as you want at any given time. 2. Make as many backup copies of this software as you want. 3. Alter the software in any manner you see fit FOR YOUR OWN PERSONAL USE. Such altered versions should not be distributed. The creation of such derivatives shall not diminish the author's title to this software. 4. Terminate this agreement at any time by destroying all copies of this software and derivatives of this software and cease distributing the same. You may not: 1. Create any derivative works from this software for distribution. 2. Re-distribute this software for commercial (for-profit) purposes. Contact the author at the address within this document if you wish to distribute this software for commercial usage, or if you have any questions about its redistribution. Disclaimer of warranty: In using this software, you understand and agree that this software is provided "as is" without warranty of any kind. The entire risk as to the results of and performance of using this software lies entirely with you, the user. The author does not make any warranties, either expressed or implied, including but not limited to implied warranties of merchantability and fitness for a particular purpose, with respect to this software. In no event shall the author be liable for any consequential, incidental, or special damages whatsoever arising out of the use or inability to use this software. */