Browse Source

Show per client connected stats instead of per user, every 10 mins

master
Con Kolivas 11 years ago
parent
commit
4168194bd0
  1. 129
      src/stratifier.c

129
src/stratifier.c

@ -48,6 +48,9 @@ struct pool_stats {
int64_t unaccounted_shares;
int64_t accounted_shares;
/* Cycle of 24 to determine which users to dump stats on */
uint8_t userstats_cycle;
/* Shares per second for 1/5/15/60 minute rolling averages */
double sps1;
double sps5;
@ -193,17 +196,6 @@ struct user_instance {
char username[128];
int id;
tv_t last_share;
time_t last_stats;
time_t start_time;
double dsps1;
double dsps5;
double dsps15;
double dsps60;
double dsps360;
double dsps1440;
int workers;
};
@ -224,13 +216,18 @@ struct stratum_instance {
int64_t diff; /* Current diff */
int64_t old_diff; /* Previous diff */
int64_t diff_change_job_id; /* Last job_id we changed diff */
double dsps5; /* Diff shares per second, 5 minute rolling average */
double dsps1; /* Diff shares per second, 1 minute rolling average */
double dsps5; /* ... 5 minute ... */
double dsps60;/* etc */
double dsps1440;
tv_t ldc; /* Last diff change */
int ssdc; /* Shares since diff change */
tv_t first_share;
tv_t last_share;
time_t start_time;
bool authorised;
bool idle;
user_instance_t *user_instance;
char *useragent;
@ -1113,13 +1110,9 @@ static user_instance_t *authorise_user(const char *workername)
ck_ilock(&instance_lock);
HASH_FIND_STR(user_instances, username, instance);
if (!instance) {
ts_t now;
/* New user instance */
instance = ckzalloc(sizeof(user_instance_t));
strcpy(instance->username, username);
ts_realtime(&now);
instance->start_time = now.tv_sec;
ck_ulock(&instance_lock);
instance->id = user_instance_id++;
@ -1183,6 +1176,7 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j
bool ret = false;
const char *buf;
int arr_size;
ts_t now;
if (unlikely(!json_is_array(params_val))) {
*err_val = json_string("params not an array");
@ -1202,8 +1196,14 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j
*err_val = json_string("Empty workername parameter");
goto out;
}
if (!memcmp(buf, ".", 1)) {
*err_val = json_string("Empty username parameter");
goto out;
}
client->user_instance = authorise_user(buf);
client->user_id = client->user_instance->id;
ts_realtime(&now);
client->start_time = now.tv_sec;
LOGNOTICE("Authorised client %d worker %s as user %s", client->id, buf,
client->user_instance->username);
@ -1253,8 +1253,7 @@ static double sane_tdiff(tv_t *end, tv_t *start)
return tdiff;
}
static void add_submit(stratum_instance_t *client, user_instance_t *instance, int diff,
bool valid)
static void add_submit(stratum_instance_t *client, int diff, bool valid)
{
double tdiff, bdiff, dsps, drr, network_diff, bias;
int64_t next_blockid, optimal;
@ -1267,16 +1266,15 @@ static void add_submit(stratum_instance_t *client, user_instance_t *instance, in
network_diff = current_workbase->network_diff;
ck_runlock(&workbase_lock);
tdiff = sane_tdiff(&now_t, &instance->last_share);
tdiff = sane_tdiff(&now_t, &client->last_share);
if (unlikely(!client->first_share.tv_sec))
copy_tv(&client->first_share, &now_t);
decay_time(&instance->dsps1, diff, tdiff, 60);
decay_time(&instance->dsps5, diff, tdiff, 300);
decay_time(&instance->dsps15, diff, tdiff, 900);
decay_time(&instance->dsps60, diff, tdiff, 3600);
decay_time(&instance->dsps360, diff, tdiff, 21600);
decay_time(&instance->dsps1440, diff, tdiff, 86400);
copy_tv(&instance->last_share, &now_t);
decay_time(&client->dsps1, diff, tdiff, 60);
decay_time(&client->dsps5, diff, tdiff, 300);
decay_time(&client->dsps60, diff, tdiff, 3600);
decay_time(&client->dsps1440, diff, tdiff, 86400);
copy_tv(&client->last_share, &now_t);
client->idle = false;
tdiff = sane_tdiff(&now_t, &client->last_share);
copy_tv(&client->last_share, &now_t);
@ -1629,7 +1627,7 @@ out_unlock:
}
} else
LOGINFO("Rejected client %d invalid share", client->id);
add_submit(client, client->user_instance, diff, result);
add_submit(client, diff, result);
/* Log shares here */
len = strlen(logdir) + strlen(client->workername) + 12;
@ -2014,33 +2012,44 @@ static const double nonces = 4294967296;
* avoid floods of stat data coming at once. */
static void update_userstats(ckpool_t *ckp)
{
user_instance_t *instance, *tmp;
stratum_instance_t *client, *tmp;
char cdfield[64];
time_t now_t;
ts_t ts_now;
json_t *val;
if (++stats.userstats_cycle > 0x1f)
stats.userstats_cycle = 0;
ts_realtime(&ts_now);
sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec);
now_t = ts_now.tv_sec;
ck_rlock(&instance_lock);
HASH_ITER(hh, user_instances, instance, tmp) {
HASH_ITER(hh, stratum_instances, client, tmp) {
double ghs1, ghs5, ghs60, ghs1440;
uint8_t cycle_mask;
int elapsed;
if (instance->last_stats > now_t - 600)
/* Only show stats from clients that have returned shares in
* the last 10 minutes */
if (client->idle)
continue;
/* Select clients using a mask to return each users's stats once
* every ~10 minutes */
cycle_mask = client->user_id & 0x1f;
if (cycle_mask != stats.userstats_cycle)
continue;
elapsed = now_t - instance->start_time;
instance->last_stats = now_t;
ghs1 = instance->dsps1 * nonces;
ghs5 = instance->dsps5 * nonces;
ghs60 = instance->dsps60 * nonces;
ghs1440 = instance->dsps1440 * nonces;
val = json_pack("{ss,si,ss,sf,sf,sf,sf,ss,ss,ss,ss}",
elapsed = now_t - client->start_time;
ghs1 = client->dsps1 * nonces;
ghs5 = client->dsps5 * nonces;
ghs60 = client->dsps60 * nonces;
ghs1440 = client->dsps1440 * nonces;
val = json_pack("{ss,si,si,ss,sf,sf,sf,sf,ss,ss,ss,ss}",
"poolinstance", ckp->name,
"instanceid", client->id,
"elapsed", elapsed,
"username", instance->username,
"username", client->user_instance->username,
"hashrate", ghs1,
"hashrate5m", ghs5,
"hashrate1hr", ghs60,
@ -2069,7 +2078,7 @@ static void *statsupdate(void *arg)
double ghs1, ghs5, ghs15, ghs60, ghs360, ghs1440, tdiff, bias;
char suffix360[16], suffix1440[16];
double sps1, sps5, sps15, sps60;
user_instance_t *instance, *tmp;
stratum_instance_t *client, *tmp;
char fname[512] = {};
tv_t now, diff;
ts_t ts_now;
@ -2151,42 +2160,36 @@ static void *statsupdate(void *arg)
fclose(fp);
ck_rlock(&instance_lock);
HASH_ITER(hh, user_instances, instance, tmp) {
HASH_ITER(hh, stratum_instances, client, tmp) {
bool idle = false;
double ghs;
if (now.tv_sec - instance->last_share.tv_sec > 60) {
if (now.tv_sec - client->last_share.tv_sec > 60) {
idle = true;
/* No shares for over a minute, decay to 0 */
decay_time(&instance->dsps1, 0, tdiff, 60);
decay_time(&instance->dsps5, 0, tdiff, 300);
decay_time(&instance->dsps15, 0, tdiff, 900);
decay_time(&instance->dsps60, 0, tdiff, 3600);
decay_time(&instance->dsps360, 0, tdiff, 21600);
decay_time(&instance->dsps1440, 0, tdiff, 86400);
decay_time(&client->dsps1, 0, tdiff, 60);
decay_time(&client->dsps5, 0, tdiff, 300);
decay_time(&client->dsps60, 0, tdiff, 3600);
decay_time(&client->dsps1440, 0, tdiff, 86400);
if (now.tv_sec - client->last_share.tv_sec > 600)
client->idle = true;
}
ghs = instance->dsps1 * nonces;
ghs = client->dsps1 * nonces;
suffix_string(ghs, suffix1, 16, 0);
ghs = instance->dsps5 * nonces;
ghs = client->dsps5 * nonces;
suffix_string(ghs, suffix5, 16, 0);
ghs = instance->dsps15 * nonces;
suffix_string(ghs, suffix15, 16, 0);
ghs = instance->dsps60 * nonces;
ghs = client->dsps60 * nonces;
suffix_string(ghs, suffix60, 16, 0);
ghs = instance->dsps360 * nonces;
suffix_string(ghs, suffix360, 16, 0);
ghs = instance->dsps1440 * nonces;
ghs = client->dsps1440 * nonces;
suffix_string(ghs, suffix1440, 16, 0);
val = json_pack("{ss,ss,ss,ss,ss,ss}",
val = json_pack("{ss,ss,ss,ss}",
"hashrate1m", suffix1,
"hashrate5m", suffix5,
"hashrate15m", suffix15,
"hashrate1hr", suffix60,
"hashrate6hr", suffix360,
"hashrate1d", suffix1440);
snprintf(fname, 511, "%s/%s", ckp->logdir, instance->username);
snprintf(fname, 511, "%s/%s", ckp->logdir, client->workername);
fp = fopen(fname, "w");
if (unlikely(!fp)) {
LOGERR("Failed to fopen %s", fname);
@ -2197,7 +2200,7 @@ static void *statsupdate(void *arg)
/* Only display the status of connected users to the
* console log. */
if (!idle)
LOGNOTICE("User %s:%s", instance->username, s);
LOGNOTICE("Worker %s:%s", client->workername, s);
dealloc(s);
json_decref(val);
fclose(fp);
@ -2221,10 +2224,10 @@ static void *statsupdate(void *arg)
"createinet", "127.0.0.1");
ckdbq_add(ID_POOLSTATS, val);
/* Update stats 4 times per minute for smooth values, displaying
/* Update stats 3 times per minute for smooth values, displaying
* status every minute. */
for (i = 0; i < 4; i++) {
cksleep_ms_r(&stats.last_update, 15000);
for (i = 0; i < 3; i++) {
cksleep_ms_r(&stats.last_update, 20000);
cksleep_prepare_r(&stats.last_update);
update_userstats(ckp);

Loading…
Cancel
Save