]> git.itanic.dy.fi Git - rrdd/blobdiff - parser.c
Parsers: Implement framework for registering and querying parsers
[rrdd] / parser.c
index 887b524e6ad12df4a89c9e69d5cf845650c2bfc9..4a5e5355d5360483a1aef22c42d0604cdd17ccbb 100644 (file)
--- a/parser.c
+++ b/parser.c
-#include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
 
 #include "parser.h"
-#include "process.h"
-#include "string.h"
 #include "debug.h"
-#include "utils.h"
 
-#define STATFILE "/proc/stat"
+static struct parser_info *parser_list;
 
-int cpu_parser(char *data, const char **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;
-}
-
-#define MEMFILE "/proc/meminfo"
-
-int mem_parser(char *data, const char **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, other = 0,
-               swaptotal = 0, total = 0;
-       FILE *file = fopen(MEMFILE, "r");
+       pr_info("Registering parser %s\n", info->name);
 
-       if (file == NULL) {
-               pr_err("Failed to open file %s\n", MEMFILE);
-               return -1;
-       }
-
-       while (fgets(buf, 1024, file)) {
-               get_word(buf, 0, word, 1024);
-               
-               if (!strcmp(word, "MemFree:")) {
-                       free = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "MemTotal:")) {
-                       total = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Buffers:")) {
-                       buffered = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Cached:")) {
-                       cache = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Active:")) {
-                       active = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Inactive:")) {
-                       inactive = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "SwapFree:")) {
-                       swapfree = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "AnonPages:")) {
-                       anon = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "Slab:")) {
-                       slab = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "PageTables:")) {
-                       tables = dec_to_int(buf, NULL);
-               } else if (!strcmp(word, "SwapTotal:")) {
-                       swaptotal = dec_to_int(buf, NULL);
-               }
-       }
-       fclose(file);
-
-       other = total - free - buffered - cache - anon - slab - tables;
-
-       snprintf(data, RRD_DATA_MAX_LEN, "%f:%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,
-               other / 1024.0,
-               (swaptotal - swapfree) / 1024.0);
-
-       return 0;
-}
-
-int cpu_mem_parser(char *data, const char **p)
-{
-       char cpu[1024], mem[1024];
-
-       cpu_parser(cpu, p);
-       mem_parser(mem, p);
-       snprintf(data, RRD_DATA_MAX_LEN, "%s:%s", cpu, mem);
-
-       return 0;
-}
-
-int digitemp_parser(char *data, const char **p)
-{
-       const char digitemp_cmd[] = "/usr/bin/digitemp";
-       char *const digitemp_args[] = { "", "-o2", "-a", "-q", 0 };
-       FILE *readf;
-       int pid, ret;
-       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;
-       }
-
-       ret = fscanf(readf, "%f %f %f", &t1, &t2, &t3);
-
-       if (ret != 3) {
-               pr_err("Failed to parse digitemp output: %m\n");
-               sprintf(data, "U:U");
-               return 1;
+       if (!parser_list) {
+               parser_list = info;
+               return 0;
        }
 
-       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;
-}
-
-int digitemp_parser_mod(char *data, const char **p)
-{
-       char buf[1024];
-       int ret;
-
-       ret = digitemp_parser(buf, p);
-       snprintf(data, RRD_DATA_MAX_LEN, "U:%s", buf);
-
-       return ret;
-}
-
-/* Run a command and feed the output from stdout directly to rrdtool */
-int script_parser(char *rrd_data, const char **parser_data)
-{
-       FILE *readf;
-       int pid, ret;
-       void *tmp = parser_data;
-       char **cmd = tmp;
+       for (parser = parser_list; parser->next; parser = parser->next)
+               ;
 
-       pid = run_piped_stream(cmd[0], &cmd[1], NULL, &readf, NULL);
-       ret = fread(rrd_data, 1, RRD_DATA_MAX_LEN, readf);
-
-       pr_info("Read %d bytes :%s\n", ret, rrd_data);
-       fclose(readf);
-
-       harvest_zombies(pid);
+       parser->next = info;
+       info->next = NULL;
 
        return 0;
 }
 
-struct iface_stats {
-       long long rx_bytes;
-       long long rx_packets;
-       long long tx_bytes;
-       long long tx_packets;
-};
-
-#define PROC_NETDEV    "/proc/net/dev"
-
-static int get_iface_stats(const char *iface, struct iface_stats *stat)
+struct parser_info *str_to_parser(const char *str)
 {
-       FILE *netdev;
-       char buf[1024];
-       char if_name[16];
-       char *str;
-       int error;
-
-       netdev = fopen(PROC_NETDEV, "r");
+       struct parser_info *parser;
 
-       if (netdev == NULL) {
-               error = errno;
-               pr_err("Failed to open file %s: %d (%m)\n",
-                       PROC_NETDEV, error);
-               return error;
+       for (parser = parser_list; parser; parser = parser->next) {
+               if (!strcmp(str, parser->name))
+                       return parser;
        }
 
-       while (fgets(buf, sizeof(buf), netdev)) {
-               get_word(buf, &str, if_name, sizeof(if_name));
-
-               /* Remove the ':' at the end of the if_name */
-               if_name[strlen(if_name) - 1] = 0;
-               if (strncmp(iface, if_name, sizeof(if_name)))
-                       continue;
-
-               stat->rx_bytes          = dec_to_longlong(str, &str);
-               stat->rx_packets        = dec_to_longlong(str, &str);
-               /* errs */                dec_to_longlong(str, &str);
-               /* drop */                dec_to_longlong(str, &str);
-               /* fifo */                dec_to_longlong(str, &str);
-               /* frame */               dec_to_longlong(str, &str);
-               /* compressed */          dec_to_longlong(str, &str);
-               /* multicast */           dec_to_longlong(str, &str);
-               stat->tx_bytes          = dec_to_longlong(str, &str);
-               stat->tx_packets        = dec_to_longlong(str, &str);
-
-               pr_info("rx_b %lld rx_p %lld tx_b %lld tx_p %lld\n",
-                       stat->rx_bytes, stat->rx_packets,
-                       stat->tx_bytes, stat->tx_packets);
-
-               return 0;
-       }
-
-       pr_err("Interface %s not found\n", iface);
-       return -ENODEV;
-}
-
-int netstats_parser(char *rrd_data, const char **parser_data)
-{
-       struct iface_stats stat;
-       const char **iface_name = parser_data;
-       int max_str = RRD_DATA_MAX_LEN;
-       int ret;
-
-       if (!parser_data) {
-               pr_err("No device names specified\n");
-               return -1;
-       }
-
-       while(*iface_name) {
-               pr_info("getting data for iface %s\n", *iface_name);
-               ret = get_iface_stats(*iface_name, &stat);
-
-               if (!ret) {
-                       ret = snprintf(rrd_data, max_str, "%lld:%lld:%lld:%lld",
-                               stat.rx_bytes, stat.rx_packets,
-                               stat.tx_bytes, stat.tx_packets);
-               } else {
-                       ret = snprintf(rrd_data, max_str, "U:U:U:U");
-               }
-
-               max_str -= ret;
-               rrd_data += ret;
-
-               iface_name++;
-               if (!*iface_name)
-                       break;
-
-               ret = snprintf(rrd_data, max_str, ":");
-               max_str -= ret;
-               rrd_data += ret;
-       }
-
-       return 0;
+       return NULL;
 }