#include "stdinc.h" #include "dat.h" #include "fns.h" int collectstats = 1; /* keep in sync with dat.h:/NStat */ Statdesc statdesc[NStat] = { { "rpc total", }, { "rpc reads", }, { "rpc reads ok", }, { "rpc reads failed", }, { "rpc read bytes", }, { "rpc read time", }, { "rpc read cached", }, { "rpc read cached time", }, { "rpc read uncached", }, { "rpc read uncached time "}, { "rpc writes", }, { "rpc writes new", }, { "rpc writes old", }, { "rpc writes failed", }, { "rpc write bytes", }, { "rpc write time", }, { "rpc write new time", }, { "rpc write old time", }, { "lump cache hits", }, { "lump cache misses", }, { "lump cache reads", }, { "lump cache writes", }, { "lump cache size", }, { "lump cache stall", }, { "lump cache read time", }, { "disk cache hits", }, { "disk cache misses", }, { "disk cache lookups", }, { "disk cache reads", }, { "disk cache writes", }, { "disk cache dirty", }, { "disk cache size", }, { "disk cache flushes", }, { "disk cache stalls", }, { "disk cache lookup time", }, { "disk block stalls", }, { "lump stalls", }, { "index cache hits", }, { "index cache misses", }, { "index cache reads", }, { "index cache writes", }, { "index cache fills", }, { "index cache prefetches", }, { "index cache dirty", }, { "index cache size", }, { "index cache flushes", }, { "index cache stalls", }, { "index cache read time", }, { "index cache lookups" }, { "index cache summary hits" }, { "index cache summary prefetches" }, { "bloom filter hits", }, { "bloom filter misses", }, { "bloom filter false misses", }, { "bloom filter lookups", }, { "bloom filter ones", }, { "bloom filter bits", }, { "arena block reads", }, { "arena block read bytes", }, { "arena block writes", }, { "arena block write bytes", }, { "isect block reads", }, { "isect block read bytes", }, { "isect block writes", }, { "isect block write bytes", }, { "sum reads", }, { "sum read bytes", }, { "cig loads" }, { "cig load time" }, }; QLock statslock; Stats stats; Stats *stathist; int nstathist; ulong statind; ulong stattime; void statsproc(void *v) { USED(v); for(;;){ stats.now = time(0); stathist[stattime%nstathist] = stats; stattime++; sleep(1000); } } void statsinit(void) { nstathist = 90000; stathist = MKNZ(Stats, nstathist); vtproc(statsproc, nil); } void setstat(int index, long val) { qlock(&statslock); stats.n[index] = val; qunlock(&statslock); } void addstat(int index, int inc) { if(!collectstats) return; qlock(&statslock); stats.n[index] += inc; qunlock(&statslock); } void addstat2(int index, int inc, int index1, int inc1) { if(!collectstats) return; qlock(&statslock); stats.n[index] += inc; stats.n[index1] += inc1; qunlock(&statslock); } void printstats(void) { } void binstats(long (*fn)(Stats *s0, Stats *s1, void *arg), void *arg, long t0, long t1, Statbin *bin, int nbin) { long xt0, t, te, v; int i, j, lo, hi, m; vlong tot; Statbin *b; t = stats.now; /* negative times mean relative to now. */ if(t0 <= 0) t0 += t; if(t1 <= 0) t1 += t; /* ten minute range if none given */ if(t1 <= t0) t0 = t1 - 60*10; if(0) fprint(2, "stats %ld-%ld\n", t0, t1); /* binary search to find t0-1 or close */ lo = stattime; hi = stattime+nstathist; while(lo+1 < hi){ m = (lo+hi)/2; if(stathist[m%nstathist].now >= t0) hi = m; else lo = m; } xt0 = stathist[lo%nstathist].now; if(xt0 >= t1){ /* no samples */ memset(bin, 0, nbin*sizeof bin[0]); return; } hi = stattime+nstathist; j = lo+1; for(i=0; insamp==0 || v < b->min) b->min = v; if(b->nsamp==0 || v > b->max) b->max = v; tot += v; b->nsamp++; } if(b->nsamp) b->avg = tot / b->nsamp; if(b->nsamp==0 && i>0) *b = bin[i-1]; } }