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) {
}
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;
}
}
// 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;
// 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
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;
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 },
};