-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(metrics) move histogram logic to its own module
- Loading branch information
Showing
21 changed files
with
448 additions
and
353 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
#ifndef DDEBUG | ||
#define DDEBUG 0 | ||
#endif | ||
#include "ddebug.h" | ||
|
||
#include <ngx_wasm.h> | ||
#include <ngx_wa_histogram.h> | ||
|
||
#define NGX_WA_MIN_BIN 5 | ||
#define NGX_WA_MAX_BIN 20 | ||
#define NGX_WA_BIN_INCREASE 5 | ||
|
||
|
||
static uint32_t | ||
bin_log2_upper_bound(ngx_int_t n) | ||
{ | ||
uint32_t upper_bound = 2; | ||
|
||
if (n < 2) { | ||
return 1; | ||
} | ||
|
||
for (n = n - 1; n >>= 1; upper_bound <<= 1) { /* void */ } | ||
|
||
return upper_bound; | ||
} | ||
|
||
|
||
static ngx_int_t | ||
histogram_grow(ngx_wa_metrics_t *metrics, ngx_wa_metrics_histogram_t *h, | ||
ngx_wa_metrics_histogram_t **out) | ||
{ | ||
size_t old_size, size; | ||
ngx_int_t rc = NGX_OK; | ||
ngx_uint_t n; | ||
ngx_wa_metrics_histogram_t *new_h = NULL; | ||
|
||
if (h->n_bins == NGX_WA_MAX_BIN) { | ||
return NGX_ERROR; | ||
} | ||
|
||
n = ngx_min(NGX_WA_BIN_INCREASE, NGX_WA_MAX_BIN - h->n_bins); | ||
old_size = sizeof(ngx_wa_metrics_histogram_t) | ||
+ sizeof(ngx_wa_metrics_bin_t) * h->n_bins; | ||
size = old_size + sizeof(ngx_wa_metrics_bin_t) * n; | ||
|
||
if (metrics->shm->eviction == NGX_WASM_SHM_EVICTION_NONE) { | ||
ngx_wasm_shm_lock(metrics->shm); | ||
} | ||
|
||
new_h = ngx_slab_calloc_locked(metrics->shm->shpool, size); | ||
if (new_h == NULL) { | ||
rc = NGX_ERROR; | ||
goto error; | ||
} | ||
|
||
ngx_memcpy(new_h, h, old_size); | ||
ngx_slab_free_locked(metrics->shm->shpool, h); | ||
|
||
new_h->n_bins += n; | ||
*out = new_h; | ||
|
||
error: | ||
|
||
if (metrics->shm->eviction == NGX_WASM_SHM_EVICTION_NONE) { | ||
ngx_wasm_shm_unlock(metrics->shm); | ||
} | ||
|
||
return rc; | ||
} | ||
|
||
|
||
static ngx_wa_metrics_bin_t * | ||
histogram_bin(ngx_wa_metrics_t *metrics, ngx_wa_metrics_histogram_t *h, | ||
ngx_uint_t n, ngx_wa_metrics_histogram_t **out) | ||
{ | ||
size_t i, j = 0; | ||
uint32_t ub = bin_log2_upper_bound(n); | ||
ngx_wa_metrics_bin_t *b; | ||
|
||
for (i = 0; i < h->n_bins; i++) { | ||
b = &h->bins[i]; | ||
j = (j == 0 && ub < b->upper_bound) ? i : j; | ||
|
||
if (b->upper_bound == ub) { | ||
return b; | ||
|
||
} else if (b->upper_bound == 0) { | ||
break; | ||
} | ||
} | ||
|
||
if (i == h->n_bins) { | ||
if (out && histogram_grow(metrics, h, out) == NGX_OK) { | ||
h = *out; | ||
|
||
} else { | ||
ngx_wasm_log_error(NGX_LOG_WARN, metrics->shm->log, 0, | ||
"cannot add a new histogram bin for value " | ||
"\"%uD\", returning next closest bin", n); | ||
return &h->bins[j]; | ||
} | ||
} | ||
|
||
/* shift bins to create space for the new one */ | ||
ngx_memcpy(&h->bins[j + 1], &h->bins[j], | ||
sizeof(ngx_wa_metrics_bin_t) * (i - j)); | ||
|
||
h->bins[j].upper_bound = ub; | ||
h->bins[j].count = 0; | ||
|
||
return &h->bins[j]; | ||
} | ||
|
||
|
||
void | ||
ngx_wa_metrics_histogram_get(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m, | ||
ngx_uint_t slots, ngx_wa_metrics_histogram_t *out) | ||
{ | ||
size_t i, j = 0; | ||
ngx_wa_metrics_bin_t *b, *out_b; | ||
ngx_wa_metrics_histogram_t *h; | ||
|
||
for (i = 0; i < slots; i++) { | ||
h = m->slots[i].histogram; | ||
|
||
for (j = 0; j < h->n_bins; j++) { | ||
b = &h->bins[j]; | ||
if (b->upper_bound == 0) { | ||
break; | ||
} | ||
|
||
out_b = histogram_bin(metrics, out, b->upper_bound, NULL); | ||
out_b->count += b->count; | ||
} | ||
} | ||
} | ||
|
||
#if (NGX_DEBUG) | ||
static void | ||
histogram_log(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m, uint32_t mid) | ||
{ | ||
size_t i, size = sizeof(ngx_wa_metrics_histogram_t) | ||
+ sizeof(ngx_wa_metrics_bin_t) | ||
* NGX_WA_MAX_BIN; | ||
ngx_wa_metrics_bin_t *b; | ||
ngx_wa_metrics_histogram_t *h; | ||
u_char *p, buf[size], s_buf[NGX_MAX_ERROR_STR]; | ||
|
||
ngx_memzero(buf, size); | ||
|
||
p = s_buf; | ||
h = (ngx_wa_metrics_histogram_t *) buf; | ||
h->n_bins = NGX_WA_MAX_BIN; | ||
h->bins[0].upper_bound = NGX_MAX_UINT32_VALUE; | ||
|
||
ngx_wa_metrics_histogram_get(metrics, m, metrics->workers, h); | ||
|
||
for (i = 0; i < h->n_bins; i++) { | ||
b = &h->bins[i]; | ||
if (b->upper_bound == 0) { | ||
break; | ||
} | ||
|
||
p = ngx_sprintf(p, " %uD: %uD;", b->upper_bound, b->count); | ||
} | ||
|
||
ngx_log_debug3(NGX_LOG_DEBUG_WASM, metrics->shm->log, 0, | ||
"histogram \"%uD\": %*s", mid, p - s_buf - 1, s_buf + 1); | ||
} | ||
#endif | ||
|
||
ngx_int_t | ||
ngx_wa_metrics_histogram_add_locked(ngx_wa_metrics_t *metrics, | ||
ngx_wa_metric_t *m) | ||
{ | ||
size_t i; | ||
uint16_t n_bins = NGX_WA_MIN_BIN; | ||
ngx_wa_metrics_histogram_t **h; | ||
|
||
for (i = 0; i < metrics->workers; i++) { | ||
h = &m->slots[i].histogram; | ||
*h = ngx_slab_calloc_locked(metrics->shm->shpool, | ||
sizeof(ngx_wa_metrics_histogram_t) | ||
+ sizeof(ngx_wa_metrics_bin_t) * n_bins); | ||
if (*h == NULL) { | ||
goto error; | ||
} | ||
|
||
(*h)->n_bins = n_bins; | ||
(*h)->bins[0].upper_bound = NGX_MAX_UINT32_VALUE; | ||
} | ||
|
||
return NGX_OK; | ||
|
||
error: | ||
|
||
for (/* void */ ; i > 0; i--) { | ||
ngx_slab_free_locked(metrics->shm->shpool, m->slots[i - 1].histogram); | ||
} | ||
|
||
return NGX_ERROR; | ||
} | ||
|
||
|
||
ngx_int_t | ||
ngx_wa_metrics_histogram_record(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m, | ||
ngx_uint_t slot, uint32_t mid, ngx_uint_t n) | ||
{ | ||
ngx_wa_metrics_bin_t *b; | ||
ngx_wa_metrics_histogram_t *h; | ||
|
||
h = m->slots[slot].histogram; | ||
b = histogram_bin(metrics, h, n, &m->slots[slot].histogram); | ||
b->count += 1; | ||
|
||
#if (NGX_DEBUG) | ||
histogram_log(metrics, m, mid); | ||
#endif | ||
|
||
return NGX_OK; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#ifndef _NGX_WA_HISTOGRAM_H_INCLUDED_ | ||
#define _NGX_WA_HISTOGRAM_H_INCLUDED_ | ||
|
||
|
||
#include <ngx_wa_metrics.h> | ||
|
||
|
||
ngx_int_t ngx_wa_metrics_histogram_add_locked(ngx_wa_metrics_t *metrics, | ||
ngx_wa_metric_t *m); | ||
ngx_int_t ngx_wa_metrics_histogram_record(ngx_wa_metrics_t *metrics, | ||
ngx_wa_metric_t *m, ngx_uint_t slot, uint32_t mid, ngx_uint_t n); | ||
void ngx_wa_metrics_histogram_get(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m, | ||
ngx_uint_t slots, ngx_wa_metrics_histogram_t *out); | ||
|
||
|
||
#endif /* _NGX_WA_HISTOGRAM_H_INCLUDED_ */ |
Oops, something went wrong.