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