xref: /dflybsd-src/usr.bin/dsynth/runstats.c (revision ea37671df32972e5ab85505aad1eaaf6a307b013)
1*ea37671dSMatthew Dillon /*
2*ea37671dSMatthew Dillon  * Copyright (c) 2019 The DragonFly Project.  All rights reserved.
3*ea37671dSMatthew Dillon  *
4*ea37671dSMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
5*ea37671dSMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
6*ea37671dSMatthew Dillon  *
7*ea37671dSMatthew Dillon  * This code uses concepts and configuration based on 'synth', by
8*ea37671dSMatthew Dillon  * John R. Marino <draco@marino.st>, which was written in ada.
9*ea37671dSMatthew Dillon  *
10*ea37671dSMatthew Dillon  * Redistribution and use in source and binary forms, with or without
11*ea37671dSMatthew Dillon  * modification, are permitted provided that the following conditions
12*ea37671dSMatthew Dillon  * are met:
13*ea37671dSMatthew Dillon  *
14*ea37671dSMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
15*ea37671dSMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
16*ea37671dSMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
17*ea37671dSMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
18*ea37671dSMatthew Dillon  *    the documentation and/or other materials provided with the
19*ea37671dSMatthew Dillon  *    distribution.
20*ea37671dSMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
21*ea37671dSMatthew Dillon  *    contributors may be used to endorse or promote products derived
22*ea37671dSMatthew Dillon  *    from this software without specific, prior written permission.
23*ea37671dSMatthew Dillon  *
24*ea37671dSMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25*ea37671dSMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26*ea37671dSMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27*ea37671dSMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
28*ea37671dSMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29*ea37671dSMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30*ea37671dSMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31*ea37671dSMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32*ea37671dSMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33*ea37671dSMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34*ea37671dSMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35*ea37671dSMatthew Dillon  * SUCH DAMAGE.
36*ea37671dSMatthew Dillon  */
37*ea37671dSMatthew Dillon 
38*ea37671dSMatthew Dillon #include "dsynth.h"
39*ea37671dSMatthew Dillon 
40*ea37671dSMatthew Dillon static runstats_t *RSBase;
41*ea37671dSMatthew Dillon static runstats_t **RSTailp = &RSBase;
42*ea37671dSMatthew Dillon static time_t RSStartTime;
43*ea37671dSMatthew Dillon 
44*ea37671dSMatthew Dillon #define RHISTSIZE       600		/* impulse record is 10 minutes */
45*ea37671dSMatthew Dillon #define ONEHOUR		(60 * 60)
46*ea37671dSMatthew Dillon 
47*ea37671dSMatthew Dillon void
48*ea37671dSMatthew Dillon RunStatsInit(void)
49*ea37671dSMatthew Dillon {
50*ea37671dSMatthew Dillon 	runstats_t *rs;
51*ea37671dSMatthew Dillon 
52*ea37671dSMatthew Dillon 	RSStartTime = time(NULL);
53*ea37671dSMatthew Dillon 
54*ea37671dSMatthew Dillon 	*RSTailp = &NCursesRunStats;
55*ea37671dSMatthew Dillon 	RSTailp = &(*RSTailp)->next;
56*ea37671dSMatthew Dillon 
57*ea37671dSMatthew Dillon 	*RSTailp = &MonitorRunStats;
58*ea37671dSMatthew Dillon 	RSTailp = &(*RSTailp)->next;
59*ea37671dSMatthew Dillon 
60*ea37671dSMatthew Dillon 	*RSTailp = &HtmlRunStats;
61*ea37671dSMatthew Dillon 	RSTailp = &(*RSTailp)->next;
62*ea37671dSMatthew Dillon 
63*ea37671dSMatthew Dillon 	for (rs = RSBase; rs; rs = rs->next)
64*ea37671dSMatthew Dillon 		rs->init();
65*ea37671dSMatthew Dillon }
66*ea37671dSMatthew Dillon 
67*ea37671dSMatthew Dillon void
68*ea37671dSMatthew Dillon RunStatsDone(void)
69*ea37671dSMatthew Dillon {
70*ea37671dSMatthew Dillon 	runstats_t *rs;
71*ea37671dSMatthew Dillon 
72*ea37671dSMatthew Dillon 	for (rs = RSBase; rs; rs = rs->next)
73*ea37671dSMatthew Dillon 		rs->done();
74*ea37671dSMatthew Dillon }
75*ea37671dSMatthew Dillon 
76*ea37671dSMatthew Dillon void
77*ea37671dSMatthew Dillon RunStatsReset(void)
78*ea37671dSMatthew Dillon {
79*ea37671dSMatthew Dillon 	runstats_t *rs;
80*ea37671dSMatthew Dillon 
81*ea37671dSMatthew Dillon 	for (rs = RSBase; rs; rs = rs->next)
82*ea37671dSMatthew Dillon 		rs->reset();
83*ea37671dSMatthew Dillon }
84*ea37671dSMatthew Dillon 
85*ea37671dSMatthew Dillon void
86*ea37671dSMatthew Dillon RunStatsUpdate(worker_t *work)
87*ea37671dSMatthew Dillon {
88*ea37671dSMatthew Dillon 	runstats_t *rs;
89*ea37671dSMatthew Dillon 
90*ea37671dSMatthew Dillon 	for (rs = RSBase; rs; rs = rs->next)
91*ea37671dSMatthew Dillon 		rs->update(work);
92*ea37671dSMatthew Dillon }
93*ea37671dSMatthew Dillon 
94*ea37671dSMatthew Dillon void
95*ea37671dSMatthew Dillon RunStatsUpdateTop(void)
96*ea37671dSMatthew Dillon {
97*ea37671dSMatthew Dillon 	static int rate_history[RHISTSIZE];
98*ea37671dSMatthew Dillon 	static u_int last_ti;
99*ea37671dSMatthew Dillon 	topinfo_t info;
100*ea37671dSMatthew Dillon 	runstats_t *rs;
101*ea37671dSMatthew Dillon 	u_int ti;
102*ea37671dSMatthew Dillon 	time_t t;
103*ea37671dSMatthew Dillon 
104*ea37671dSMatthew Dillon 	/*
105*ea37671dSMatthew Dillon 	 * Time
106*ea37671dSMatthew Dillon 	 */
107*ea37671dSMatthew Dillon 	bzero(&info, sizeof(info));
108*ea37671dSMatthew Dillon 	t = time(NULL) - RSStartTime;
109*ea37671dSMatthew Dillon 	info.s = t % 60;
110*ea37671dSMatthew Dillon 	info.m = t / 60 % 60;
111*ea37671dSMatthew Dillon 	info.h = t / 60 / 60;
112*ea37671dSMatthew Dillon 
113*ea37671dSMatthew Dillon 	/*
114*ea37671dSMatthew Dillon 	 * Easy fields
115*ea37671dSMatthew Dillon 	 */
116*ea37671dSMatthew Dillon 	info.total = BuildTotal;
117*ea37671dSMatthew Dillon 	info.successful = BuildSuccessCount;
118*ea37671dSMatthew Dillon 	info.ignored = BuildIgnoreCount;
119*ea37671dSMatthew Dillon 	info.remaining = BuildTotal - BuildCount;
120*ea37671dSMatthew Dillon 	info.failed = BuildFailCount;
121*ea37671dSMatthew Dillon 	info.skipped = BuildSkipCount;
122*ea37671dSMatthew Dillon 
123*ea37671dSMatthew Dillon 	/*
124*ea37671dSMatthew Dillon 	 * Load and swap
125*ea37671dSMatthew Dillon 	 */
126*ea37671dSMatthew Dillon 	getloadavg(info.dload, 3);
127*ea37671dSMatthew Dillon 	info.dswap = getswappct(&info.noswap) * 100.0;
128*ea37671dSMatthew Dillon 
129*ea37671dSMatthew Dillon 	/*
130*ea37671dSMatthew Dillon 	 * Rate and 10-minute impulse
131*ea37671dSMatthew Dillon 	 */
132*ea37671dSMatthew Dillon 	if (t > 20)
133*ea37671dSMatthew Dillon 		info.pkgrate = (BuildSuccessCount + BuildFailCount) *
134*ea37671dSMatthew Dillon 			       ONEHOUR / t;
135*ea37671dSMatthew Dillon 	else
136*ea37671dSMatthew Dillon 		info.pkgrate = 0;
137*ea37671dSMatthew Dillon 	ti = (u_int)((unsigned long)t % RHISTSIZE);
138*ea37671dSMatthew Dillon 	rate_history[ti] = BuildSuccessCount + BuildFailCount;
139*ea37671dSMatthew Dillon #if 0
140*ea37671dSMatthew Dillon 	dlog(DLOG_ALL, "ti[%3d] = %d\n", ti, rate_history[ti]);
141*ea37671dSMatthew Dillon #endif
142*ea37671dSMatthew Dillon 	while (last_ti != ti) {
143*ea37671dSMatthew Dillon 		rate_history[last_ti] = rate_history[ti];
144*ea37671dSMatthew Dillon 		last_ti = (last_ti + 1) % RHISTSIZE;
145*ea37671dSMatthew Dillon 	}
146*ea37671dSMatthew Dillon 
147*ea37671dSMatthew Dillon 	if (t < 20) {
148*ea37671dSMatthew Dillon 		info.pkgimpulse = 0;
149*ea37671dSMatthew Dillon 	} else if (t < RHISTSIZE) {
150*ea37671dSMatthew Dillon 		info.pkgimpulse = rate_history[ti] -
151*ea37671dSMatthew Dillon 				  rate_history[(ti - t) % RHISTSIZE];
152*ea37671dSMatthew Dillon 		info.pkgimpulse = info.pkgimpulse * ONEHOUR / t;
153*ea37671dSMatthew Dillon 	} else {
154*ea37671dSMatthew Dillon 		info.pkgimpulse = rate_history[ti] -
155*ea37671dSMatthew Dillon 				  rate_history[(ti + 1) % RHISTSIZE];
156*ea37671dSMatthew Dillon 		info.pkgimpulse = info.pkgimpulse * ONEHOUR / RHISTSIZE;
157*ea37671dSMatthew Dillon #if 0
158*ea37671dSMatthew Dillon 		dlog(DLOG_ALL, "pkgimpulse %d - %d -> %d\n",
159*ea37671dSMatthew Dillon 		     rate_history[ti],
160*ea37671dSMatthew Dillon 		     rate_history[(ti + 1) % RHISTSIZE],
161*ea37671dSMatthew Dillon 		     info.pkgimpulse);
162*ea37671dSMatthew Dillon #endif
163*ea37671dSMatthew Dillon 	}
164*ea37671dSMatthew Dillon 
165*ea37671dSMatthew Dillon 	/*
166*ea37671dSMatthew Dillon 	 * Issue update
167*ea37671dSMatthew Dillon 	 */
168*ea37671dSMatthew Dillon 	for (rs = RSBase; rs; rs = rs->next)
169*ea37671dSMatthew Dillon 		rs->updateTop(&info);
170*ea37671dSMatthew Dillon }
171*ea37671dSMatthew Dillon 
172*ea37671dSMatthew Dillon void
173*ea37671dSMatthew Dillon RunStatsUpdateLogs(void)
174*ea37671dSMatthew Dillon {
175*ea37671dSMatthew Dillon 	runstats_t *rs;
176*ea37671dSMatthew Dillon 
177*ea37671dSMatthew Dillon 	for (rs = RSBase; rs; rs = rs->next)
178*ea37671dSMatthew Dillon 		rs->updateLogs();
179*ea37671dSMatthew Dillon }
180*ea37671dSMatthew Dillon 
181*ea37671dSMatthew Dillon void
182*ea37671dSMatthew Dillon RunStatsSync(void)
183*ea37671dSMatthew Dillon {
184*ea37671dSMatthew Dillon 	runstats_t *rs;
185*ea37671dSMatthew Dillon 
186*ea37671dSMatthew Dillon 	for (rs = RSBase; rs; rs = rs->next)
187*ea37671dSMatthew Dillon 		rs->sync();
188*ea37671dSMatthew Dillon }
189