xref: /plan9/sys/src/cmd/venti/srv/stats.c (revision 23566e0c4b9b5ce80121325d240a2f6e83a70a8f)
1368c31abSDavid du Colombier #include "stdinc.h"
2368c31abSDavid du Colombier #include "dat.h"
3368c31abSDavid du Colombier #include "fns.h"
4368c31abSDavid du Colombier 
5368c31abSDavid du Colombier int collectstats = 1;
6368c31abSDavid du Colombier 
7368c31abSDavid du Colombier /* keep in sync with dat.h:/NStat */
8368c31abSDavid du Colombier Statdesc statdesc[NStat] =
9368c31abSDavid du Colombier {
10368c31abSDavid du Colombier 	{ "rpc total", },
11368c31abSDavid du Colombier 	{ "rpc reads", },
12368c31abSDavid du Colombier 	{ "rpc reads ok", },
13368c31abSDavid du Colombier 	{ "rpc reads failed", },
14368c31abSDavid du Colombier 	{ "rpc read bytes", },
15368c31abSDavid du Colombier 	{ "rpc read time", },
16368c31abSDavid du Colombier 	{ "rpc read cached", },
17368c31abSDavid du Colombier 	{ "rpc read cached time", },
18368c31abSDavid du Colombier 	{ "rpc read uncached", },
19368c31abSDavid du Colombier 	{ "rpc read uncached time "},
20368c31abSDavid du Colombier 
21368c31abSDavid du Colombier 	{ "rpc writes", },
22368c31abSDavid du Colombier 	{ "rpc writes new", },
23368c31abSDavid du Colombier 	{ "rpc writes old", },
24368c31abSDavid du Colombier 	{ "rpc writes failed", },
25368c31abSDavid du Colombier 	{ "rpc write bytes", },
26368c31abSDavid du Colombier 	{ "rpc write time", },
27368c31abSDavid du Colombier 	{ "rpc write new time", },
28368c31abSDavid du Colombier 	{ "rpc write old time", },
29368c31abSDavid du Colombier 
30368c31abSDavid du Colombier 	{ "lump cache hits", },
31368c31abSDavid du Colombier 	{ "lump cache misses", },
32368c31abSDavid du Colombier 	{ "lump cache reads", },
33368c31abSDavid du Colombier 	{ "lump cache writes", },
34368c31abSDavid du Colombier 	{ "lump cache size", },
35368c31abSDavid du Colombier 	{ "lump cache stall", },
36368c31abSDavid du Colombier 	{ "lump cache read time", },
37368c31abSDavid du Colombier 
38368c31abSDavid du Colombier 	{ "disk cache hits", },
39368c31abSDavid du Colombier 	{ "disk cache misses", },
40368c31abSDavid du Colombier 	{ "disk cache lookups", },
41368c31abSDavid du Colombier 	{ "disk cache reads", },
42368c31abSDavid du Colombier 	{ "disk cache writes", },
43368c31abSDavid du Colombier 	{ "disk cache dirty", },
44368c31abSDavid du Colombier 	{ "disk cache size", },
45368c31abSDavid du Colombier 	{ "disk cache flushes", },
46368c31abSDavid du Colombier 	{ "disk cache stalls", },
47368c31abSDavid du Colombier 	{ "disk cache lookup time", },
48368c31abSDavid du Colombier 
49368c31abSDavid du Colombier 	{ "disk block stalls", },
50368c31abSDavid du Colombier 	{ "lump stalls", },
51368c31abSDavid du Colombier 
52368c31abSDavid du Colombier 	{ "index cache hits", },
53368c31abSDavid du Colombier 	{ "index cache misses", },
54368c31abSDavid du Colombier 	{ "index cache reads", },
55368c31abSDavid du Colombier 	{ "index cache writes", },
56368c31abSDavid du Colombier 	{ "index cache fills", },
57368c31abSDavid du Colombier 	{ "index cache prefetches", },
58368c31abSDavid du Colombier 	{ "index cache dirty", },
59368c31abSDavid du Colombier 	{ "index cache size", },
60368c31abSDavid du Colombier 	{ "index cache flushes", },
61368c31abSDavid du Colombier 	{ "index cache stalls", },
62368c31abSDavid du Colombier 	{ "index cache read time", },
63*f9e1cf08SDavid du Colombier 	{ "index cache lookups" },
64*f9e1cf08SDavid du Colombier 	{ "index cache summary hits" },
65*f9e1cf08SDavid du Colombier 	{ "index cache summary prefetches" },
66368c31abSDavid du Colombier 
67368c31abSDavid du Colombier 	{ "bloom filter hits", },
68368c31abSDavid du Colombier 	{ "bloom filter misses", },
69368c31abSDavid du Colombier 	{ "bloom filter false misses", },
70368c31abSDavid du Colombier 	{ "bloom filter lookups", },
71368c31abSDavid du Colombier 	{ "bloom filter ones", },
72368c31abSDavid du Colombier 	{ "bloom filter bits", },
73368c31abSDavid du Colombier 
74368c31abSDavid du Colombier 	{ "arena block reads", },
75368c31abSDavid du Colombier 	{ "arena block read bytes", },
76368c31abSDavid du Colombier 	{ "arena block writes", },
77368c31abSDavid du Colombier 	{ "arena block write bytes", },
78368c31abSDavid du Colombier 
79368c31abSDavid du Colombier 	{ "isect block reads", },
80368c31abSDavid du Colombier 	{ "isect block read bytes", },
81368c31abSDavid du Colombier 	{ "isect block writes", },
82368c31abSDavid du Colombier 	{ "isect block write bytes", },
83368c31abSDavid du Colombier 
84368c31abSDavid du Colombier 	{ "sum reads", },
85368c31abSDavid du Colombier 	{ "sum read bytes", },
86*f9e1cf08SDavid du Colombier 
87*f9e1cf08SDavid du Colombier 	{ "cig loads" },
88*f9e1cf08SDavid du Colombier 	{ "cig load time" },
89368c31abSDavid du Colombier };
90368c31abSDavid du Colombier 
91368c31abSDavid du Colombier QLock statslock;
92368c31abSDavid du Colombier Stats stats;
93368c31abSDavid du Colombier Stats *stathist;
94368c31abSDavid du Colombier int nstathist;
95368c31abSDavid du Colombier ulong statind;
96368c31abSDavid du Colombier ulong stattime;
97368c31abSDavid du Colombier 
98368c31abSDavid du Colombier void
statsproc(void * v)99368c31abSDavid du Colombier statsproc(void *v)
100368c31abSDavid du Colombier {
101368c31abSDavid du Colombier 	USED(v);
102368c31abSDavid du Colombier 
103368c31abSDavid du Colombier 	for(;;){
104368c31abSDavid du Colombier 		stats.now = time(0);
105368c31abSDavid du Colombier 		stathist[stattime%nstathist] = stats;
106368c31abSDavid du Colombier 		stattime++;
107368c31abSDavid du Colombier 		sleep(1000);
108368c31abSDavid du Colombier 	}
109368c31abSDavid du Colombier }
110368c31abSDavid du Colombier 
111368c31abSDavid du Colombier void
statsinit(void)112368c31abSDavid du Colombier statsinit(void)
113368c31abSDavid du Colombier {
114368c31abSDavid du Colombier 	nstathist = 90000;
115368c31abSDavid du Colombier 	stathist = MKNZ(Stats, nstathist);
116368c31abSDavid du Colombier 	vtproc(statsproc, nil);
117368c31abSDavid du Colombier }
118368c31abSDavid du Colombier 
119368c31abSDavid du Colombier void
setstat(int index,long val)120368c31abSDavid du Colombier setstat(int index, long val)
121368c31abSDavid du Colombier {
122368c31abSDavid du Colombier 	qlock(&statslock);
123368c31abSDavid du Colombier 	stats.n[index] = val;
124368c31abSDavid du Colombier 	qunlock(&statslock);
125368c31abSDavid du Colombier }
126368c31abSDavid du Colombier 
127368c31abSDavid du Colombier void
addstat(int index,int inc)128368c31abSDavid du Colombier addstat(int index, int inc)
129368c31abSDavid du Colombier {
130368c31abSDavid du Colombier 	if(!collectstats)
131368c31abSDavid du Colombier 		return;
132368c31abSDavid du Colombier 	qlock(&statslock);
133368c31abSDavid du Colombier 	stats.n[index] += inc;
134368c31abSDavid du Colombier 	qunlock(&statslock);
135368c31abSDavid du Colombier }
136368c31abSDavid du Colombier 
137368c31abSDavid du Colombier void
addstat2(int index,int inc,int index1,int inc1)138368c31abSDavid du Colombier addstat2(int index, int inc, int index1, int inc1)
139368c31abSDavid du Colombier {
140368c31abSDavid du Colombier 	if(!collectstats)
141368c31abSDavid du Colombier 		return;
142368c31abSDavid du Colombier 	qlock(&statslock);
143368c31abSDavid du Colombier 	stats.n[index] += inc;
144368c31abSDavid du Colombier 	stats.n[index1] += inc1;
145368c31abSDavid du Colombier 	qunlock(&statslock);
146368c31abSDavid du Colombier }
147368c31abSDavid du Colombier 
148368c31abSDavid du Colombier void
printstats(void)149368c31abSDavid du Colombier printstats(void)
150368c31abSDavid du Colombier {
151368c31abSDavid du Colombier }
152368c31abSDavid du Colombier 
153368c31abSDavid du Colombier void
binstats(long (* fn)(Stats * s0,Stats * s1,void * arg),void * arg,long t0,long t1,Statbin * bin,int nbin)154368c31abSDavid du Colombier binstats(long (*fn)(Stats *s0, Stats *s1, void *arg), void *arg,
155368c31abSDavid du Colombier 	long t0, long t1, Statbin *bin, int nbin)
156368c31abSDavid du Colombier {
157368c31abSDavid du Colombier 	long xt0, t, te, v;
158368c31abSDavid du Colombier 	int i, j, lo, hi, m;
159368c31abSDavid du Colombier 	vlong tot;
160368c31abSDavid du Colombier 	Statbin *b;
161368c31abSDavid du Colombier 
162368c31abSDavid du Colombier 	t = stats.now;
163368c31abSDavid du Colombier 
164368c31abSDavid du Colombier 	/* negative times mean relative to now. */
165368c31abSDavid du Colombier 	if(t0 <= 0)
166368c31abSDavid du Colombier 		t0 += t;
167368c31abSDavid du Colombier 	if(t1 <= 0)
168368c31abSDavid du Colombier 		t1 += t;
169368c31abSDavid du Colombier 	/* ten minute range if none given */
170368c31abSDavid du Colombier 	if(t1 <= t0)
171368c31abSDavid du Colombier 		t0 = t1 - 60*10;
172368c31abSDavid du Colombier 	if(0) fprint(2, "stats %ld-%ld\n", t0, t1);
173368c31abSDavid du Colombier 
174368c31abSDavid du Colombier 	/* binary search to find t0-1 or close */
175368c31abSDavid du Colombier 	lo = stattime;
176368c31abSDavid du Colombier 	hi = stattime+nstathist;
177368c31abSDavid du Colombier 	while(lo+1 < hi){
178368c31abSDavid du Colombier 		m = (lo+hi)/2;
179368c31abSDavid du Colombier 		if(stathist[m%nstathist].now >= t0)
180368c31abSDavid du Colombier 			hi = m;
181368c31abSDavid du Colombier 		else
182368c31abSDavid du Colombier 			lo = m;
183368c31abSDavid du Colombier 	}
184368c31abSDavid du Colombier 	xt0 = stathist[lo%nstathist].now;
185368c31abSDavid du Colombier 	if(xt0 >= t1){
186368c31abSDavid du Colombier 		/* no samples */
187368c31abSDavid du Colombier 		memset(bin, 0, nbin*sizeof bin[0]);
188368c31abSDavid du Colombier 		return;
189368c31abSDavid du Colombier 	}
190368c31abSDavid du Colombier 
191368c31abSDavid du Colombier 	hi = stattime+nstathist;
192368c31abSDavid du Colombier 	j = lo+1;
193368c31abSDavid du Colombier 	for(i=0; i<nbin; i++){
194368c31abSDavid du Colombier 		te = t0 + (t1-t0)*i/nbin;
195368c31abSDavid du Colombier 		b = &bin[i];
196368c31abSDavid du Colombier 		memset(b, 0, sizeof *b);
197368c31abSDavid du Colombier 		tot = 0;
198368c31abSDavid du Colombier 		for(; j<hi && stathist[j%nstathist].now<te; j++){
199368c31abSDavid du Colombier 			v = fn(&stathist[(j-1)%nstathist], &stathist[j%nstathist], arg);
200368c31abSDavid du Colombier 			if(b->nsamp==0 || v < b->min)
201368c31abSDavid du Colombier 				b->min = v;
202368c31abSDavid du Colombier 			if(b->nsamp==0 || v > b->max)
203368c31abSDavid du Colombier 				b->max = v;
204368c31abSDavid du Colombier 			tot += v;
205368c31abSDavid du Colombier 			b->nsamp++;
206368c31abSDavid du Colombier 		}
207368c31abSDavid du Colombier 		if(b->nsamp)
208368c31abSDavid du Colombier 			b->avg = tot / b->nsamp;
209368c31abSDavid du Colombier 		if(b->nsamp==0 && i>0)
210368c31abSDavid du Colombier 			*b = bin[i-1];
211368c31abSDavid du Colombier 	}
212368c31abSDavid du Colombier }
213