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