Skip to content

Commit

Permalink
contrib: add better formats
Browse files Browse the repository at this point in the history
Signed-off-by: hexian000 <[email protected]>
  • Loading branch information
hexian000 committed Jun 4, 2023
1 parent 88dc8fe commit 1016038
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 24 deletions.
4 changes: 3 additions & 1 deletion contrib/csnippets/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
target_sources(csnippets
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/buffer.c"
"${CMAKE_CURRENT_SOURCE_DIR}/formats.c"
"${CMAKE_CURRENT_SOURCE_DIR}/slog.c"
PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/arraysize.h"
"${CMAKE_CURRENT_SOURCE_DIR}/buffer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/check.h"
"${CMAKE_CURRENT_SOURCE_DIR}/formats.h"
"${CMAKE_CURRENT_SOURCE_DIR}/mcache.h"
"${CMAKE_CURRENT_SOURCE_DIR}/minmax.h"
"${CMAKE_CURRENT_SOURCE_DIR}/serialize.h"
"${CMAKE_CURRENT_SOURCE_DIR}/buffer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/slog.h"
)

Expand Down
102 changes: 102 additions & 0 deletions contrib/csnippets/utils/formats.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* csnippets (c) 2019-2023 He Xian <[email protected]>
* This code is licensed under MIT license (see LICENSE for details) */

#include "formats.h"
#include "utils/arraysize.h"
#include "utils/minmax.h"

#include <stdint.h>
#include <stdio.h>
#include <math.h>

struct duration make_duration(double value)
{
if (!isfinite(value)) {
return (struct duration){ 0 };
}
struct duration d;
if (value < 0.0) {
d.sign = -1;
value = -value;
} else {
d.sign = 1;
}
d.nanos = (unsigned int)floor(fmod(value * 1e+9, 1000.0));
d.micros = (unsigned int)floor(fmod(value * 1e+6, 1000.0));
d.millis = (unsigned int)floor(fmod(value * 1e+3, 1000.0));
d.seconds = (unsigned int)floor(fmod(value, 60.0));
value /= 60.0;
d.minutes = (unsigned int)floor(fmod(value, 60.0));
value /= 60.0;
d.hours = (unsigned int)floor(fmod(value, 24.0));
value /= 24.0;
d.days = (unsigned int)floor(value);
return d;
}

struct duration make_duration_nanos(int64_t value)
{
struct duration d;
if (value < INT64_C(0)) {
d.sign = -1;
value = -value;
} else {
d.sign = 1;
}
d.nanos = (unsigned int)(value % 1000);
value /= 1000;
d.micros = (unsigned int)(value % 1000);
value /= 1000;
d.millis = (unsigned int)(value % 1000);
value /= 1000;
d.seconds = (unsigned int)(value % 60);
value /= 60;
d.minutes = (unsigned int)(value % 60);
value /= 60;
d.hours = (unsigned int)(value % 24);
value /= 24;
d.days = (unsigned int)value;
return d;
}

static const char *iec_units[] = {
"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB",
};

int format_iec_bytes(char *buf, const size_t bufsize, const double value)
{
if (!isfinite(value) || (value < 8192.0)) {
return snprintf(buf, bufsize, "%.0lf %s", value, iec_units[0]);
}
const int x = ((int)log2(value) - 3) / 10;
const int n = (int)ARRAY_SIZE(iec_units) - 1;
const int i = CLAMP(x, 0, n);
const double v = ldexp(value, i * -10);
if (v < 10.0) {
return snprintf(buf, bufsize, "%.02lf %s", v, iec_units[i]);
}
if (v < 100.0) {
return snprintf(buf, bufsize, "%.01lf %s", v, iec_units[i]);
}
return snprintf(buf, bufsize, "%.0lf %s", v, iec_units[i]);
}

int format_duration_seconds(char *b, const size_t size, const struct duration d)
{
if (d.days) {
return snprintf(
b, size, "%dd%02u:%02u:%02u", d.sign * (int)d.days,
d.hours, d.minutes, d.seconds);
} else if (d.hours) {
return snprintf(
b, size, "%d:%02u:%02u", d.sign * (int)d.hours,
d.minutes, d.seconds);
} else if (d.minutes) {
return snprintf(
b, size, "%d:%02u", d.sign * (int)d.minutes, d.seconds);
}
if (d.sign < 0) {
return snprintf(b, size, "-%u", d.seconds);
}
return snprintf(b, size, "%u", d.seconds);
}
28 changes: 28 additions & 0 deletions contrib/csnippets/utils/formats.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* csnippets (c) 2019-2023 He Xian <[email protected]>
* This code is licensed under MIT license (see LICENSE for details) */

#ifndef FORMATS_H
#define FORMATS_H

#include <stddef.h>
#include <stdint.h>

int format_iec_bytes(char *buf, size_t bufsize, double value);

struct duration {
signed int sign; /* +1 or -1, 0 is null, otherwise undefined */
unsigned int days;
unsigned int hours;
unsigned int minutes;
unsigned int seconds;
unsigned int millis;
unsigned int micros;
unsigned int nanos;
};

struct duration make_duration(double seconds);
struct duration make_duration_nanos(int64_t nanos);

int format_duration_seconds(char *b, size_t size, struct duration d);

#endif /* FORMATS_H */
17 changes: 12 additions & 5 deletions src/obfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "utils/arraysize.h"
#include "utils/buffer.h"
#include "utils/formats.h"
#include "utils/slog.h"
#include "utils/check.h"
#include "algo/hashtable.h"
Expand Down Expand Up @@ -903,20 +904,26 @@ obfs_stats(struct obfs *restrict obfs, struct vbuffer *restrict buf)
};

const double dpkt_cap = (double)(dstats.pkt_cap) / dt;
const double dbyt_cap = (double)(dstats.byt_cap) * 0x1p-10 / dt;
const double dbyt_rx = (double)(dstats.byt_rx) * 0x1p-10 / dt;
const uintmax_t pkt_drop = stats->pkt_cap - stats->pkt_rx;
const double byt_drop =
(double)(stats->byt_cap - stats->byt_rx) * 0x1p-10;
const int num_ctx = table_size(obfs->contexts);
const size_t unauthenticated = obfs->unauthenticated;
assert(0 <= num_ctx && unauthenticated <= (size_t)num_ctx);
const size_t authenticated = (size_t)num_ctx - unauthenticated;

#define FORMAT_BYTES(name, value) \
char name[16]; \
(void)format_iec_bytes(name, sizeof(name), (value))

FORMAT_BYTES(dbyt_cap, dstats.byt_cap / dt);
FORMAT_BYTES(dbyt_rx, dstats.byt_rx / dt);
FORMAT_BYTES(byt_drop, (double)(stats->byt_cap - stats->byt_rx));

return vbuf_appendf(
stats_ctx.buf,
"obfs: %zu(+%zu) contexts, capture %.1lf pkt/s, cap/rx %.1lf/%.1lf KiB/s, drop: %ju (%.1lf KiB)\n",
"obfs: %zu(+%zu) contexts, capture %.1lf/s (%s/s), rx %s/s, drop: %ju (%s)\n",
authenticated, unauthenticated, dpkt_cap, dbyt_cap, dbyt_rx,
pkt_drop, byt_drop);
#undef FORMAT_BYTES
}

bool obfs_start(struct obfs *restrict obfs, struct server *restrict s)
Expand Down
43 changes: 25 additions & 18 deletions src/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "server.h"
#include "utils/slog.h"
#include "utils/buffer.h"
#include "utils/formats.h"
#include "algo/hashtable.h"
#include "algo/xorshift.h"
#include "conf.h"
Expand Down Expand Up @@ -494,7 +495,8 @@ print_session_table(struct server *restrict s, struct vbuffer *restrict buf)
ctx.num_in_state[STATE_TIME_WAIT]);
}

struct vbuffer *server_stats(struct server *s, struct vbuffer *restrict buf)
struct vbuffer *
server_stats(struct server *restrict s, struct vbuffer *restrict buf)
{
buf = print_session_table(s, buf);

Expand All @@ -510,25 +512,30 @@ struct vbuffer *server_stats(struct server *s, struct vbuffer *restrict buf)
.pkt_tx = stats->pkt_tx - last_stats->pkt_tx,
};

const double dtcp_rx = (double)(dstats.tcp_rx) * 0x1p-10 / dt;
const double dtcp_tx = (double)(dstats.tcp_tx) * 0x1p-10 / dt;
const double dkcp_rx = (double)(dstats.kcp_rx) * 0x1p-10 / dt;
const double dkcp_tx = (double)(dstats.kcp_tx) * 0x1p-10 / dt;
const double deff_rx = dtcp_tx / dkcp_rx * 100.0;
const double deff_tx = dtcp_rx / dkcp_tx * 100.0;

const double tcp_rx = (double)(stats->tcp_rx) * 0x1p-10;
const double tcp_tx = (double)(stats->tcp_tx) * 0x1p-10;
const double kcp_rx = (double)(stats->kcp_rx) * 0x1p-10;
const double kcp_tx = (double)(stats->kcp_tx) * 0x1p-10;
const double pkt_rx = (double)(stats->pkt_rx) * 0x1p-10;
const double pkt_tx = (double)(stats->pkt_tx) * 0x1p-10;
#define FORMAT_BYTES(name, value) \
char name[16]; \
(void)format_iec_bytes(name, sizeof(name), (value))

FORMAT_BYTES(dtcp_rx, dstats.tcp_rx / dt);
FORMAT_BYTES(dtcp_tx, dstats.tcp_tx / dt);
FORMAT_BYTES(dkcp_rx, dstats.kcp_rx / dt);
FORMAT_BYTES(dkcp_tx, dstats.kcp_tx / dt);
const double deff_rx = dstats.tcp_tx * 100.0 / dstats.kcp_rx;
const double deff_tx = dstats.tcp_rx * 100.0 / dstats.kcp_tx;
FORMAT_BYTES(tcp_rx, (double)(stats->tcp_rx));
FORMAT_BYTES(tcp_tx, (double)(stats->tcp_tx));
FORMAT_BYTES(kcp_rx, (double)(stats->kcp_rx));
FORMAT_BYTES(kcp_tx, (double)(stats->kcp_tx));
FORMAT_BYTES(pkt_rx, (double)(stats->pkt_rx));
FORMAT_BYTES(pkt_tx, (double)(stats->pkt_tx));

return vbuf_appendf(
buf,
"traffic stats (rx/tx, in KiB):\n"
" current tcp: %.1lf/%.1lf; kcp: %.1lf/%.1lf; efficiency: %.1lf%%/%.1lf%%\n"
" total tcp: %.1lf/%.1lf; kcp: %.1lf/%.1lf; pkt: %.1lf/%.1lf\n",
"traffic stats (rx/tx):\n"
" current tcp: %s/%s; kcp: %s/%s; efficiency: %.1lf%%/%.1lf%%\n"
" total tcp: %s/%s; kcp: %s/%s; pkt: %s/%s\n",
dtcp_rx, dtcp_tx, dkcp_rx, dkcp_tx, deff_rx, deff_tx, /* dt */
tcp_rx, tcp_tx, kcp_rx, kcp_tx, pkt_rx, pkt_tx);
tcp_rx, tcp_tx, kcp_rx, kcp_tx, pkt_rx, pkt_tx /* total */
);
#undef FORMAT_BYTES
}

0 comments on commit 1016038

Please sign in to comment.