From: Michael Tremer Date: Wed, 8 Oct 2025 16:02:39 +0000 (+0000) Subject: file: Implement parsing multiple values per line X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2c5bfba9a5ca29dafea135aaf52f620cbbde8ec3;p=telemetry.git file: Implement parsing multiple values per line Signed-off-by: Michael Tremer --- diff --git a/src/daemon/file.c b/src/daemon/file.c index 71153e3..d18b80f 100644 --- a/src/daemon/file.c +++ b/src/daemon/file.c @@ -192,9 +192,10 @@ ERROR: return r; } -static int collecty_file_check_pattern(collecty_file* self, const char* s) { +static unsigned int collecty_file_check_pattern(collecty_file* self, const char* s) { const char* p = s; - int counter = 0; + + unsigned int counter = 0; // Count all % while (*p) { @@ -212,25 +213,18 @@ static int collecty_file_check_pattern(collecty_file* self, const char* s) { } static int collecty_file_check_parser(collecty_file* self, collecty_file_parser* parser) { + unsigned int patterns = 0; + // Check all elements for (collecty_file_parser* p = parser; p->s; p++) { - switch (collecty_file_check_pattern(self, p->s)) { - // Complain if there is no format character, but we can continue here - case 0: - ERROR(self->ctx, "Parser pattern has no value defined: %s\n", p->s); - break; - - // We require exactly one format character - case 1: - if (unlikely(!p->v)) { - ERROR(self->ctx, "Pattern has no target defined: %s\n", p->s); - return -EINVAL; - } - break; - - default: - ERROR(self->ctx, "Too many values defined: %s\n", p->s); - return -EINVAL; + // Count all patterns + patterns = collecty_file_check_pattern(self, p->s); + + // Fail if we don't have enough patterns + if (p->n != patterns) { + ERROR(self->ctx, "Incorrect pattern defined, need %u value(s), got %d: %s\n", + p->n, patterns, p->s); + return -EINVAL; } } @@ -248,7 +242,7 @@ static int __collecty_file_parse(collecty_ctx* ctx, collecty_file* self, // Run the parser for (collecty_file_parser* p = parser; p->s; p++) { - r = sscanf(line, p->s, p->v); + r = sscanf(line, p->s, p->v1, p->v2, p->v3, p->v4); if (r < 0) return -errno; diff --git a/src/daemon/file.h b/src/daemon/file.h index 9f51ac0..766d269 100644 --- a/src/daemon/file.h +++ b/src/daemon/file.h @@ -45,10 +45,28 @@ int collecty_file_walk(collecty_file* self, // Parser typedef struct collecty_file_parser { + // Pattern const char* s; - void* v; + + // Number of values + const unsigned int n; + + // Values + void* v1; + void* v2; + void* v3; + void* v4; } collecty_file_parser; +#define PARSE1(_s, _v1) \ + { .s = _s, .n = 1, .v1 = _v1 } +#define PARSE2(_s, _v1, _v2) \ + { .s = _s, .n = 2, .v1 = _v1, .v2 = _v2 } +#define PARSE3(_s, _v1, _v2, _v3) \ + { .s = _s, .n = 3, .v1 = _v1, .v2 = _v2, .v3 = _v3 } +#define PARSE4(_s, _v1, _v2, _v3, _v4) \ + { .s = _s, .n = 4, .v1 = _v1, .v2 = _v2, .v3 = _v3, .v4 = _v4 } + int collecty_file_parse(collecty_file* self, collecty_file_parser* parser); // Shorthands diff --git a/src/daemon/proc.c b/src/daemon/proc.c index 07d171a..e8a6bd9 100644 --- a/src/daemon/proc.c +++ b/src/daemon/proc.c @@ -32,23 +32,23 @@ int collecty_proc_read_meminfo(collecty_ctx* ctx, collecty_proc_meminfo* meminfo) { collecty_file_parser parser[] = { - { "MemTotal: %lu kB", &meminfo->mem_total, }, - { "MemFree: %lu kB", &meminfo->mem_free, }, - { "MemAvailable: %lu kB", &meminfo->mem_available, }, - { "Cached: %lu kB", &meminfo->cached, }, - { "Buffers: %lu kB", &meminfo->buffers, }, - { "Active: %lu kB", &meminfo->active, }, - { "Inactive: %lu kB", &meminfo->inactive, }, - { "Active(anon): %lu kB", &meminfo->active_anon, }, - { "Inactive(anon): %lu kB", &meminfo->inactive_anon, }, - { "Active(file): %lu kB", &meminfo->active_file, }, - { "Inactive(file): %lu kB", &meminfo->inactive_file, }, - { "SwapTotal: %lu kB", &meminfo->swap_total, }, - { "SwapFree: %lu kB", &meminfo->swap_free, }, - { "Shmem: %lu kB", &meminfo->shmem, }, - { "Slab: %lu kB", &meminfo->slab, }, - { "SReclaimable: %lu kB", &meminfo->sreclaimable, }, - { "SUnreclaim: %lu kB", &meminfo->sunreclaim, }, + PARSE1("MemTotal: %lu kB", &meminfo->mem_total), + PARSE1("MemFree: %lu kB", &meminfo->mem_free), + PARSE1("MemAvailable: %lu kB", &meminfo->mem_available), + PARSE1("Cached: %lu kB", &meminfo->cached), + PARSE1("Buffers: %lu kB", &meminfo->buffers), + PARSE1("Active: %lu kB", &meminfo->active), + PARSE1("Inactive: %lu kB", &meminfo->inactive), + PARSE1("Active(anon): %lu kB", &meminfo->active_anon), + PARSE1("Inactive(anon): %lu kB", &meminfo->inactive_anon), + PARSE1("Active(file): %lu kB", &meminfo->active_file), + PARSE1("Inactive(file): %lu kB", &meminfo->inactive_file), + PARSE1("SwapTotal: %lu kB", &meminfo->swap_total), + PARSE1("SwapFree: %lu kB", &meminfo->swap_free), + PARSE1("Shmem: %lu kB", &meminfo->shmem), + PARSE1("Slab: %lu kB", &meminfo->slab), + PARSE1("SReclaimable: %lu kB", &meminfo->sreclaimable), + PARSE1("SUnreclaim: %lu kB", &meminfo->sunreclaim), { NULL }, }; int r; diff --git a/src/daemon/sources/unbound.c b/src/daemon/sources/unbound.c index 21c7cc2..731788e 100644 --- a/src/daemon/sources/unbound.c +++ b/src/daemon/sources/unbound.c @@ -38,13 +38,13 @@ static int unbound_on_success(collecty_ctx* ctx, int r; collecty_file_parser parser[] = { - { "total.num.queries=%lu", &queries }, - { "total.num.cachehits=%lu", &cachehits }, - { "total.num.cachemiss=%lu", &cachemiss }, - { "total.num.prefetch=%lu", &prefetch }, - { "total.num.recursivereplies=%lu", &rec_replies }, - { "total.recursion.time.avg=%lf", &rec_time_avg }, - { "total.recursion.time.median=%lu", &rec_time_median }, + PARSE1("total.num.queries=%lu", &queries), + PARSE1("total.num.cachehits=%lu", &cachehits), + PARSE1("total.num.cachemiss=%lu", &cachemiss), + PARSE1("total.num.prefetch=%lu", &prefetch), + PARSE1("total.num.recursivereplies=%lu", &rec_replies), + PARSE1("total.recursion.time.avg=%lf", &rec_time_avg), + PARSE1("total.recursion.time.median=%lu", &rec_time_median), { NULL }, };