mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-26 16:20:21 +00:00
267 lines
7.5 KiB
C
267 lines
7.5 KiB
C
#include "uwsgi.h"
|
|
/*
|
|
utility functions for fast generating json output for the stats subsystem
|
|
*/
|
|
|
|
struct uwsgi_stats *uwsgi_stats_new(size_t chunk_size) {
|
|
struct uwsgi_stats *us = uwsgi_malloc(sizeof(struct uwsgi_stats));
|
|
us->base = uwsgi_malloc(chunk_size);
|
|
us->base[0] = '{';
|
|
us->base[1] = '\n';
|
|
us->pos = 2;
|
|
us->chunk = chunk_size;
|
|
us->size = chunk_size;
|
|
us->tabs = 1;
|
|
return us;
|
|
}
|
|
|
|
int uwsgi_stats_symbol(struct uwsgi_stats *us, char sym) {
|
|
char *ptr = us->base + us->pos;
|
|
char *watermark = us->base + us->size;
|
|
|
|
if (ptr+1 > watermark) {
|
|
char *new_base = realloc(us->base, us->size + us->chunk);
|
|
if (!new_base) return -1;
|
|
us->base = new_base;
|
|
us->size += us->chunk;
|
|
ptr = us->base + us->pos;
|
|
}
|
|
|
|
*ptr = sym;
|
|
us->pos++;
|
|
return 0;
|
|
}
|
|
|
|
int uwsgi_stats_symbol_nl(struct uwsgi_stats *us, char sym) {
|
|
if (uwsgi_stats_symbol(us, sym)) {
|
|
return -1;
|
|
}
|
|
return uwsgi_stats_symbol(us, '\n');
|
|
}
|
|
|
|
|
|
int uwsgi_stats_comma(struct uwsgi_stats *us) {
|
|
return uwsgi_stats_symbol_nl(us, ',');
|
|
}
|
|
|
|
int uwsgi_stats_apply_tabs(struct uwsgi_stats *us) {
|
|
size_t i;
|
|
for(i=0;i<us->tabs;i++) {
|
|
if (uwsgi_stats_symbol(us, '\t')) return -1;
|
|
};
|
|
return 0;
|
|
}
|
|
|
|
|
|
int uwsgi_stats_object_open(struct uwsgi_stats *us) {
|
|
if (uwsgi_stats_apply_tabs(us)) return -1;
|
|
us->tabs++;
|
|
return uwsgi_stats_symbol_nl(us, '{');
|
|
}
|
|
|
|
int uwsgi_stats_object_close(struct uwsgi_stats *us) {
|
|
if (uwsgi_stats_symbol(us, '\n')) return -1;
|
|
us->tabs--;
|
|
if (uwsgi_stats_apply_tabs(us)) return -1;
|
|
return uwsgi_stats_symbol(us, '}');
|
|
}
|
|
|
|
int uwsgi_stats_list_open(struct uwsgi_stats *us) {
|
|
us->tabs++;
|
|
return uwsgi_stats_symbol_nl(us, '[');
|
|
}
|
|
|
|
int uwsgi_stats_list_close(struct uwsgi_stats *us) {
|
|
if (uwsgi_stats_symbol(us, '\n')) return -1;
|
|
us->tabs--;
|
|
if (uwsgi_stats_apply_tabs(us)) return -1;
|
|
return uwsgi_stats_symbol(us, ']');
|
|
}
|
|
|
|
int uwsgi_stats_keyval(struct uwsgi_stats *us, char *key, char *value) {
|
|
|
|
if (uwsgi_stats_apply_tabs(us)) return -1;
|
|
|
|
char *ptr = us->base + us->pos;
|
|
char *watermark = us->base + us->size;
|
|
size_t available = watermark - ptr ;
|
|
|
|
int ret = snprintf(ptr, available, "\"%s\":\"%s\"", key, value);
|
|
if (ret < 0) return -1;
|
|
while (ret >= (int) available) {
|
|
char *new_base = realloc(us->base, us->size + us->chunk);
|
|
if (!new_base) return -1;
|
|
us->base = new_base;
|
|
us->size += us->chunk;
|
|
ptr = us->base + us->pos;
|
|
watermark = us->base + us->size;
|
|
available = watermark - ptr ;
|
|
ret = snprintf(ptr, available, "\"%s\":\"%s\"", key, value);
|
|
if (ret < 0) return -1;
|
|
}
|
|
|
|
us->pos += ret;
|
|
return 0;
|
|
|
|
}
|
|
|
|
int uwsgi_stats_keyval_comma(struct uwsgi_stats *us, char *key, char *value) {
|
|
int ret = uwsgi_stats_keyval(us, key, value);
|
|
if (ret) return -1;
|
|
return uwsgi_stats_comma(us);
|
|
}
|
|
|
|
int uwsgi_stats_keyvalnum(struct uwsgi_stats *us, char *key, char *value, unsigned long long num) {
|
|
|
|
if (uwsgi_stats_apply_tabs(us)) return -1;
|
|
|
|
char *ptr = us->base + us->pos;
|
|
char *watermark = us->base + us->size;
|
|
size_t available = watermark - ptr ;
|
|
|
|
int ret = snprintf(ptr, available, "\"%s\":\"%s%llu\"", key, value, num);
|
|
if (ret < 0) return -1;
|
|
while (ret >= (int) available) {
|
|
char *new_base = realloc(us->base, us->size + us->chunk);
|
|
if (!new_base) return -1;
|
|
us->base = new_base;
|
|
us->size += us->chunk;
|
|
ptr = us->base + us->pos;
|
|
watermark = us->base + us->size;
|
|
available = watermark - ptr ;
|
|
ret = snprintf(ptr, available, "\"%s\":\"%s%llu\"", key, value, num);
|
|
if (ret < 0) return -1;
|
|
}
|
|
|
|
us->pos += ret;
|
|
return 0;
|
|
|
|
}
|
|
|
|
int uwsgi_stats_keyvalnum_comma(struct uwsgi_stats *us, char *key, char *value, unsigned long long num) {
|
|
int ret = uwsgi_stats_keyvalnum(us, key, value, num);
|
|
if (ret) return -1;
|
|
return uwsgi_stats_comma(us);
|
|
}
|
|
|
|
|
|
int uwsgi_stats_keyvaln(struct uwsgi_stats *us, char *key, char *value, int vallen) {
|
|
|
|
if (uwsgi_stats_apply_tabs(us)) return -1;
|
|
|
|
char *ptr = us->base + us->pos;
|
|
char *watermark = us->base + us->size;
|
|
size_t available = watermark - ptr ;
|
|
|
|
int ret = snprintf(ptr, available, "\"%s\":\"%.*s\"", key, vallen, value);
|
|
if (ret < 0) return -1;
|
|
while (ret >= (int) available) {
|
|
char *new_base = realloc(us->base, us->size + us->chunk);
|
|
if (!new_base) return -1;
|
|
us->base = new_base;
|
|
us->size += us->chunk;
|
|
ptr = us->base + us->pos;
|
|
watermark = us->base + us->size;
|
|
available = watermark - ptr ;
|
|
ret = snprintf(ptr, available, "\"%s\":\"%.*s\"", key, vallen, value);
|
|
if (ret < 0) return -1;
|
|
}
|
|
|
|
us->pos += ret;
|
|
return 0;
|
|
|
|
}
|
|
|
|
int uwsgi_stats_keyvaln_comma(struct uwsgi_stats *us, char *key, char *value, int vallen) {
|
|
int ret = uwsgi_stats_keyvaln(us, key, value, vallen);
|
|
if (ret) return -1;
|
|
return uwsgi_stats_comma(us);
|
|
}
|
|
|
|
|
|
int uwsgi_stats_key(struct uwsgi_stats *us, char *key) {
|
|
|
|
if (uwsgi_stats_apply_tabs(us)) return -1;
|
|
|
|
char *ptr = us->base + us->pos;
|
|
char *watermark = us->base + us->size;
|
|
size_t available = watermark - ptr ;
|
|
|
|
int ret = snprintf(ptr, available, "\"%s\":", key);
|
|
if (ret < 0) return -1;
|
|
while (ret >= (int) available) {
|
|
char *new_base = realloc(us->base, us->size + us->chunk);
|
|
if (!new_base) return -1;
|
|
us->base = new_base;
|
|
us->size += us->chunk;
|
|
ptr = us->base + us->pos;
|
|
watermark = us->base + us->size;
|
|
available = watermark - ptr ;
|
|
ret = snprintf(ptr, available, "\"%s\":", key);
|
|
if (ret < 0) return -1;
|
|
}
|
|
|
|
us->pos += ret;
|
|
return 0;
|
|
}
|
|
|
|
int uwsgi_stats_str(struct uwsgi_stats *us, char *str) {
|
|
|
|
char *ptr = us->base + us->pos;
|
|
char *watermark = us->base + us->size;
|
|
size_t available = watermark - ptr ;
|
|
|
|
int ret = snprintf(ptr, available, "\"%s\"", str);
|
|
if (ret < 0) return -1;
|
|
while (ret >= (int) available) {
|
|
char *new_base = realloc(us->base, us->size + us->chunk);
|
|
if (!new_base) return -1;
|
|
us->base = new_base;
|
|
us->size += us->chunk;
|
|
ptr = us->base + us->pos;
|
|
watermark = us->base + us->size;
|
|
available = watermark - ptr ;
|
|
ret = snprintf(ptr, available, "\"%s\"", str);
|
|
if (ret < 0) return -1;
|
|
}
|
|
|
|
us->pos += ret;
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
int uwsgi_stats_keylong(struct uwsgi_stats *us, char *key, unsigned long long num) {
|
|
|
|
if (uwsgi_stats_apply_tabs(us)) return -1;
|
|
|
|
char *ptr = us->base + us->pos;
|
|
char *watermark = us->base + us->size;
|
|
size_t available = watermark - ptr ;
|
|
|
|
int ret = snprintf(ptr, available, "\"%s\":%llu", key, num);
|
|
if (ret < 0) return -1;
|
|
while (ret >= (int) available) {
|
|
char *new_base = realloc(us->base, us->size + us->chunk);
|
|
if (!new_base) return -1;
|
|
us->base = new_base;
|
|
us->size += us->chunk;
|
|
ptr = us->base + us->pos;
|
|
watermark = us->base + us->size;
|
|
available = watermark - ptr ;
|
|
ret = snprintf(ptr, available, "\"%s\":%llu", key, num);
|
|
if (ret < 0) return -1;
|
|
}
|
|
|
|
us->pos += ret;
|
|
return 0;
|
|
}
|
|
|
|
|
|
int uwsgi_stats_keylong_comma(struct uwsgi_stats *us, char *key, unsigned long long num) {
|
|
int ret = uwsgi_stats_keylong(us, key, num);
|
|
if (ret) return -1;
|
|
return uwsgi_stats_comma(us);
|
|
}
|