-#include <stdlib.h>
-#include <stdio.h>
#include <string.h>
-#include <error.h>
#include "parser.h"
-#include "process.h"
-#include "string.h"
#include "debug.h"
+#include "plugin_manager.h"
-#define STATFILE "/proc/stat"
+static struct parser_info *parser_list;
-int cpu_parser(char *data, void *p)
+int register_parser(struct parser_info *info)
{
- char buf[1024];
- char *str = buf;
- FILE *file = fopen(STATFILE, "r");
- long long user, nice, sys, idle, wait, irq, softirq;
+ struct parser_info *parser;
- if (file == NULL) {
- pr_err("Failed to open file %s\n", STATFILE);
+ if (!info->name) {
+ pr_err("Unable to register parser without a name\n");
return -1;
}
- if (!fgets(buf, 1024, file)) {
- pr_err("Failed to read file %s\n", STATFILE);
- fclose(file);
- return -1;
- }
-
- user = dec_to_longlong(str, &str);
- nice = dec_to_longlong(str, &str);
- sys = dec_to_longlong(str, &str);
- idle = dec_to_longlong(str, &str);
- wait = dec_to_longlong(str, &str);
- irq = dec_to_longlong(str, &str);
- softirq = dec_to_longlong(str, &str);
-
- snprintf(data, RRD_DATA_MAX_LEN, "%lld:%lld:%lld:%lld:%lld:%lld:%lld",
- user, nice, sys, idle, wait, irq, softirq);
-
- fclose(file);
- return 0;
-}
+ pr_info("Registering parser %s\n", info->name);
-#define MEMFILE "/proc/meminfo"
-
-int mem_parser(char *data, void *p)
-{
- char buf[1024], word[1024];
- int free = 0, buffered = 0, cache = 0, active = 0, inactive = 0,
- swapfree = 0, anon = 0, slab = 0, tables = 0, swaptotal = 0;
- FILE *file = fopen(MEMFILE, "r");
-
- if (file == NULL) {
- pr_err("Failed to open file %s\n", MEMFILE);
- return -1;
+ if (!parser_list) {
+ parser_list = info;
+ return 0;
}
- while (fgets(buf, 1024, file)) {
- get_word(buf, 0, word, 1024);
-
- if (!strcmp(word, "MemFree:")) {
- free = dec_to_int(buf, 0);
- } else if (!strcmp(word, "Buffers:")) {
- buffered = dec_to_int(buf, 0);
- } else if (!strcmp(word, "Cached:")) {
- cache = dec_to_int(buf, 0);
- } else if (!strcmp(word, "Active:")) {
- active = dec_to_int(buf, 0);
- } else if (!strcmp(word, "Inactive:")) {
- inactive = dec_to_int(buf, 0);
- } else if (!strcmp(word, "SwapFree:")) {
- swapfree = dec_to_int(buf, 0);
- } else if (!strcmp(word, "AnonPages:")) {
- anon = dec_to_int(buf, 0);
- } else if (!strcmp(word, "Slab:")) {
- slab = dec_to_int(buf, 0);
- } else if (!strcmp(word, "PageTables:")) {
- tables = dec_to_int(buf, 0);
- } else if (!strcmp(word, "SwapTotal:")) {
- swaptotal = dec_to_int(buf, 0);
- }
- }
- fclose(file);
-
- snprintf(data, RRD_DATA_MAX_LEN, "%f:%f:%f:%f:%f:%f:%f:%f:%f:%f",
- free / 1024.0,
- buffered / 1024.0,
- cache / 1024.0,
- active / 1024.0,
- inactive / 1024.0,
- swapfree / 1024.0,
- anon / 1024.0,
- slab / 1024.0,
- tables / 1024.0,
- (swaptotal - swapfree) / 1024.0);
+ for (parser = parser_list; parser->next; parser = parser->next)
+ ;
- return 0;
-}
-
-int cpu_mem_parser(char *data, void *p)
-{
- char cpu[1024], mem[1024];
-
- cpu_parser(cpu, p);
- mem_parser(mem, p);
- snprintf(data, RRD_DATA_MAX_LEN, "%s:%s", cpu, mem);
+ parser->next = info;
+ info->next = NULL;
return 0;
}
-int digitemp_parser(char *data, void *p)
+static struct parser_info *_str_to_parser(const char *str)
{
- const char digitemp_cmd[] = "/usr/bin/digitemp";
- char *const digitemp_args[] = { "", "-o2", "-a", "-q", 0 };
- FILE *readf;
- int pid, ret, error;
- float t1 = 0, t2 = 0, t3 = 0;
- char buf[1024];
-
- pid = run_piped_stream(digitemp_cmd, digitemp_args, 0, &readf, 0);
- if (pid < 0) {
- pr_err("Failed to parse digitemp\n");
- sprintf(data, "U:U");
- return -1;
- }
+ struct parser_info *parser;
- ret = fscanf(readf, "%f %f %f", &t1, &t2, &t3);
-
- if (ret != 3) {
- error = errno;
- pr_err("Failed to parse digitemp output: %s\n",
- strerror(error));
- sprintf(data, "U:U");
- return 1;
+ for (parser = parser_list; parser; parser = parser->next) {
+ if (!strcmp(str, parser->name))
+ return parser;
}
- t2 += 2.16;
- t3 += -0.44;
-
- /* Read whatever the process might be still printing out */
- while (fgets(buf, 1024, readf));
-
- harvest_zombies(pid);
- snprintf(data, RRD_DATA_MAX_LEN, "%.2f:%.2f", t3, t2);
- return 0;
+ return NULL;
}
-int digitemp_parser_mod(char *data, void *p)
+struct parser_info *str_to_parser(const char *str)
{
- char buf[1024];
+ struct parser_info *parser;
int ret;
- ret = digitemp_parser(buf, p);
- snprintf(data, RRD_DATA_MAX_LEN, "U:%s", buf);
+ parser = _str_to_parser(str);
+
+ if (parser)
+ return parser;
+
+ /* No parser found? Try loading a plugin */
+ ret = load_parser_plugin(str);
+ if (ret)
+ return NULL;
- return ret;
+ /* Try finding the parser again, maybe we got lucky and have it now */
+ return _str_to_parser(str);
}