Commit 3bfbdba9 authored by Per Cederqvist's avatar Per Cederqvist
Browse files

(check_stat): Only check a single statistics. Now static.

(check_all_stats): New name for former check_stat.  All callers updated.
(name): New static function.
(get_stats_description): New protocol request.
(get_stats): New protocol request.
parent ffabdcd8
......@@ -31,13 +31,23 @@
#endif
#include <assert.h>
#include <stdlib.h>
#include "timewrap.h"
#include <string.h>
#include <stdio.h>
#include <setjmp.h>
#include "stats.h"
#include "log.h"
#include "lyskomd.h"
#include "kom-types.h"
#include "services.h"
#include "async.h"
#include "com.h"
#include "connections.h"
#include "kom-errno.h"
#include "manipulate.h"
#include "server/smalloc.h"
#define FACT_00 (1) /* 1 second */
#define FACT_0 (15) /* 15 seconds */
......@@ -246,7 +256,7 @@ update_stat(enum stat_type st,
s->value = 0;
}
#ifdef DEBUG_STATS
if (check_stat("update_stats") > 0)
if (check_stat("update_stat") > 0)
{
kom_log("This was caused by an update of delta=%ld for type %d\n",
delta, st);
......@@ -258,46 +268,162 @@ update_stat(enum stat_type st,
#endif
}
extern int
check_stat(const char *when)
static int
check_stat(enum stat_type st,
const char *when)
{
struct avg_status *s;
double acc;
double err;
float val;
int st;
int f;
int i;
int changes = 0;
for (st = 0; st < NUM_STAT; st++)
/* FIXME: This could be rewritten so that it makes a single pass
through the avg_history. There is no real need to scan the
first parts once for each factor. */
s = &status[st];
for (f = 0; f < N_FACTS; f++)
{
s = &status[st];
for (f = 0; f < N_FACTS; f++)
acc = 0;
for (i = 0; i < factors[f]; i++)
{
acc = 0;
for (i = 0; i < factors[f]; i++)
{
val = s->avg_history[ind(s->when.tv_sec, -i-1)];
assert(val >= 0);
acc += val;
}
acc /= factors[f];
err = acc - s->avenrun[f];
if (err < 0)
err = -err;
if ((acc < 1e-6 && err > 1e-5)
|| (acc >= 1e-6 && err / acc > 0.01))
{
kom_log("Accumulated rounding errors fixed (%s) after"
" %ld updates (type=%d, f=%d, factor=%d): %f => %f\n",
when,
s->updates[f], st, f, factors[f], s->avenrun[f], acc);
s->avenrun[f] = acc;
s->updates[f] = 0;
changes++;
}
val = s->avg_history[ind(s->when.tv_sec, -i-1)];
assert(val >= 0);
acc += val;
}
acc /= factors[f];
err = acc - s->avenrun[f];
if (err < 0)
err = -err;
if ((acc < 1e-6 && err > 1e-5)
|| (acc >= 1e-6 && err / acc > 0.01))
{
kom_log("Accumulated rounding errors fixed (%s) after"
" %ld updates (type=%d, f=%d, factor=%d): %f => %f\n",
when,
s->updates[f], st, f, factors[f], s->avenrun[f], acc);
s->avenrun[f] = acc;
s->updates[f] = 0;
changes++;
}
}
return changes;
}
int
check_all_stats(const char *when)
{
enum stat_type st;
int changes = 0;
for (st = 0; st < NUM_STAT; st++)
changes += check_stat(st, when);
return changes;
}
static const char *
name(enum stat_type st)
{
switch (st)
{
case STAT_RUN_QUEUE:
return "run-queue-length";
case STAT_DNS_QUEUE:
return "pending-dns";
case STAT_IDENT_QUEUE:
return "pending-ident";
case STAT_CLIENTS:
return "clients";
case STAT_PROCESSED_CALLS:
return "req-rate";
case STAT_PROCESSED_DNS:
return "dns-rate";
case STAT_PROCESSED_IDENT:
return "ident-rate";
case STAT_RUN_QUEUE_ENTER:
return "run-queue-enter";
case STAT_RUN_QUEUE_LEAVE:
return "run-queue-leave";
case NUM_STAT:
abort();
}
abort();
}
extern Success
get_stats_description(Stats_description *result)
{
enum stat_type st;
int i;
CHK_CONNECTION(FAILURE);
result->no_of_stats = NUM_STAT;
result->stat_names = tmp_alloc(NUM_STAT * sizeof(result->stat_names[0]));
for (st = 0; st < NUM_STAT; st++)
result->stat_names[st] = s_fcrea_str(name(st));
result->intervals.length = N_FACTS + 1;
result->intervals.data = tmp_alloc(
(N_FACTS + 1) * sizeof(result->intervals.data[0]));
result->intervals.data[0] = 0; /* The first momentaneous value. */
for (i = 0; i < N_FACTS; i++)
result->intervals.data[i+1] = factors[i];
return OK;
}
extern Success
get_stats(const String what,
Number_list *result)
{
enum stat_type st;
int i;
CHK_CONNECTION(FAILURE);
for (st = 0; st < NUM_STAT; st++)
if (s_streq(what, s_fcrea_str(name(st))))
break;
if (st == NUM_STAT)
{
kom_errno = KOM_UNDEFINED_MEASUREMENT;
err_stat = 0;
return FAILURE;
}
/* Make sure we get the curren statistics, not some old value. */
update_stat(st, 0);
check_stat(st, "get_stats");
result->length = N_FACTS + 1;
result->data = tmp_alloc((N_FACTS + 1) * sizeof(result->data[0]));
if (st < STAT_FIRST_EVENT)
result->data[0] = 100 * status[st].value + 0.5;
else
result->data[0] = 0;
for (i = 0; i < N_FACTS; i++)
result->data[i+1] = 100 * status[st].avenrun[i] + 0.5;
return OK;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment