Skip to content

Commit

Permalink
refactor(metrics) move histogram logic to its own module
Browse files Browse the repository at this point in the history
  • Loading branch information
casimiro committed May 9, 2024
1 parent cd55097 commit 8fb4bdd
Show file tree
Hide file tree
Showing 21 changed files with 448 additions and 353 deletions.
2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ NGX_WASMX_DEPS="\
$ngx_addon_dir/src/common/shm/ngx_wasm_shm.h \
$ngx_addon_dir/src/common/shm/ngx_wasm_shm_kv.h \
$ngx_addon_dir/src/common/shm/ngx_wasm_shm_queue.h \
$ngx_addon_dir/src/common/metrics/ngx_wa_histogram.h \
$ngx_addon_dir/src/common/metrics/ngx_wa_metrics.h"

NGX_WASMX_SRCS="\
Expand All @@ -158,6 +159,7 @@ NGX_WASMX_SRCS="\
$ngx_addon_dir/src/common/shm/ngx_wasm_shm.c \
$ngx_addon_dir/src/common/shm/ngx_wasm_shm_kv.c \
$ngx_addon_dir/src/common/shm/ngx_wasm_shm_queue.c \
$ngx_addon_dir/src/common/metrics/ngx_wa_histogram.c \
$ngx_addon_dir/src/common/metrics/ngx_wa_metrics.c"

# wasm
Expand Down
222 changes: 222 additions & 0 deletions src/common/metrics/ngx_wa_histogram.c
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;
}
16 changes: 16 additions & 0 deletions src/common/metrics/ngx_wa_histogram.h
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_ */
Loading

0 comments on commit 8fb4bdd

Please sign in to comment.