about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--collector.h31
-rw-r--r--cpu.c2
-rw-r--r--diskstats.c2
-rw-r--r--filesystem.c2
-rw-r--r--hwmon.c2
-rw-r--r--main.c107
-rw-r--r--meminfo.c2
-rw-r--r--netdev.c2
-rw-r--r--scrape.c8
-rw-r--r--scrape.h13
-rw-r--r--stat.c2
-rw-r--r--test/cpu_test.c1
-rw-r--r--test/diskstats_test.c1
-rw-r--r--test/filesystem_test.c1
-rw-r--r--test/hwmon_test.c1
-rw-r--r--test/meminfo_test.c1
-rw-r--r--test/netdev_test.c1
-rw-r--r--test/stat_test.c1
-rw-r--r--test/textfile_test.c1
-rw-r--r--test/uname_test.c1
-rw-r--r--textfile.c2
-rw-r--r--uname.c2
22 files changed, 78 insertions, 108 deletions
diff --git a/collector.h b/collector.h
deleted file mode 100644
index 7ac5ef5..0000000
--- a/collector.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2018 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef NANO_EXPORTER_COLLECTOR_H_
-#define NANO_EXPORTER_COLLECTOR_H_ 1
-
-#include "stdbool.h"
-
-#include "scrape.h"
-
-struct collector {
-  const char *name;
-  void (*collect)(scrape_req *req, void *ctx);
-  void *(*init)(int argc, char *argv[]);
-  bool has_args;
-};
-
-#endif // NANO_EXPORTER_COLLECTOR_H_
diff --git a/cpu.c b/cpu.c
index f8bc030..34942dd 100644
--- a/cpu.c
+++ b/cpu.c
@@ -19,7 +19,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 // limits for CPU numbers
diff --git a/diskstats.c b/diskstats.c
index 9e4ecd1..1cabd95 100644
--- a/diskstats.c
+++ b/diskstats.c
@@ -20,7 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 // size of input buffer for paths and lines
diff --git a/filesystem.c b/filesystem.c
index bda569a..ec34bc3 100644
--- a/filesystem.c
+++ b/filesystem.c
@@ -19,7 +19,7 @@
 #include <string.h>
 #include <sys/statvfs.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 // size of input buffer for paths and lines
diff --git a/hwmon.c b/hwmon.c
index cccc209..705028a 100644
--- a/hwmon.c
+++ b/hwmon.c
@@ -23,7 +23,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 // size of input buffer for paths and lines
diff --git a/main.c b/main.c
index 43a0917..d45b3d4 100644
--- a/main.c
+++ b/main.c
@@ -25,7 +25,6 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
-#include "collector.h"
 #include "scrape.h"
 #include "util.h"
 
@@ -44,9 +43,8 @@ static const struct collector *collectors[] = {
   XCOLLECTORS
 };
 #undef X
-#define NCOLLECTORS (sizeof collectors / sizeof *collectors)
+#define NCOLLECTORS ((unsigned) (sizeof collectors / sizeof *collectors))
 
-enum tristate { flag_off = -1, flag_undef = 0, flag_on = 1 };
 
 struct config {
   const char *port;
@@ -60,27 +58,20 @@ const struct config default_config = {
   .pidfile = 0,
 };
 
-struct handler_ctx {
-  struct {
-    enum tristate enabled;
-    struct slist *args;
-    struct slist **next_arg;
-    void *ctx;
-  } collectors[NCOLLECTORS];
+struct collector_ctx {
+  unsigned enabled;
+  const struct collector *coll[NCOLLECTORS];
+  void *coll_ctx[NCOLLECTORS];
 };
 
-static bool parse_args(int argc, char *argv[], struct config *cfg, struct handler_ctx *ctx);
-static bool initialize(struct handler_ctx *ctx, int max_args);
+static bool initialize(int argc, char *argv[], struct config *cfg, struct collector_ctx *ctx);
 static bool daemonize(struct config *cfg);
-static void handler(scrape_req *req, void *ctx_ptr);
 
 int main(int argc, char *argv[]) {
   struct config cfg = default_config;
-  struct handler_ctx ctx;
+  struct collector_ctx ctx;
 
-  if (!parse_args(argc, argv, &cfg, &ctx))
-    return 1;
-  if (!initialize(&ctx, argc > 0 ? argc - 1 : 0))
+  if (!initialize(argc, argv, &cfg, &ctx))
     return 1;
 
   scrape_server *server = scrape_listen(cfg.port);
@@ -91,17 +82,24 @@ int main(int argc, char *argv[]) {
     if (!daemonize(&cfg))
       return 1;
 
-  scrape_serve(server, handler, &ctx);
+  scrape_serve(server, ctx.enabled, ctx.coll, ctx.coll_ctx);
   scrape_close(server);
 
   return 0;
 }
 
-static bool parse_args(int argc, char *argv[], struct config *cfg, struct handler_ctx *ctx) {
-  for (size_t i = 0; i < NCOLLECTORS; i++) {
-    ctx->collectors[i].args = 0;
-    ctx->collectors[i].next_arg = &ctx->collectors[i].args;
-    ctx->collectors[i].enabled = flag_undef;
+static bool initialize(int argc, char *argv[], struct config *cfg, struct collector_ctx *ctx) {
+  // parse command-line arguments
+
+  enum tristate { flag_off = -1, flag_undef = 0, flag_on = 1 };
+  enum tristate coll_enabled[NCOLLECTORS];
+  struct { struct slist *args; struct slist **next_arg; unsigned count; } coll_args[NCOLLECTORS];
+
+  for (unsigned i = 0; i < NCOLLECTORS; i++) {
+    coll_enabled[i] = flag_undef;
+    coll_args[i].args = 0;
+    coll_args[i].next_arg = &coll_args[i].args;
+    coll_args[i].count = 0;
   }
 
   enum tristate enabled_default = flag_on;
@@ -109,19 +107,20 @@ static bool parse_args(int argc, char *argv[], struct config *cfg, struct handle
   for (int arg = 1; arg < argc; arg++) {
     // check for collector arguments
 
-    for (size_t i = 0; i < NCOLLECTORS; i++) {
+    for (unsigned i = 0; i < NCOLLECTORS; i++) {
       size_t name_len = strlen(collectors[i]->name);
       if (strncmp(argv[arg], "--", 2) == 0
           && strncmp(argv[arg] + 2, collectors[i]->name, name_len) == 0
           && argv[arg][2 + name_len] == '-') {
         char *carg = argv[arg] + 2 + name_len + 1;
         if (strcmp(carg, "on") == 0) {
-          ctx->collectors[i].enabled = flag_on;
+          coll_enabled[i] = flag_on;
           enabled_default = flag_off;
         } else if (strcmp(carg, "off") == 0) {
-          ctx->collectors[i].enabled = flag_off;
+          coll_enabled[i] = flag_off;
         } else if (collectors[i]->init && collectors[i]->has_args) {
-          ctx->collectors[i].next_arg = slist_append(ctx->collectors[i].next_arg, carg);
+          coll_args[i].next_arg = slist_append(coll_args[i].next_arg, carg);
+          coll_args[i].count++;
         } else {
           fprintf(stderr, "unknown argument: %s (collector %s takes no arguments)\n", argv[arg], collectors[i]->name);
           return false;
@@ -149,30 +148,43 @@ static bool parse_args(int argc, char *argv[], struct config *cfg, struct handle
  next_arg: ;
   }
 
-  for (size_t i = 0; i < NCOLLECTORS; i++)
-    if (ctx->collectors[i].enabled == flag_undef)
-      ctx->collectors[i].enabled = enabled_default;
+  unsigned max_args = 1;
 
-  return true;
-}
+  for (unsigned i = 0; i < NCOLLECTORS; i++) {
+    if (coll_enabled[i] == flag_undef)
+      coll_enabled[i] = enabled_default;
+    if (coll_enabled[i] == flag_on && coll_args[i].count > max_args)
+      max_args = coll_args[i].count;
+  }
+
+  // prepare the list of enabled collectors, and initialize them
 
-static bool initialize(struct handler_ctx *ctx, int max_args) {
-  int argc;
-  char *argv[max_args + 1];
+  unsigned coll_argc;
+  char *coll_argv[max_args + 1];
 
-  for (size_t i = 0; i < NCOLLECTORS; i++) {
-    if (ctx->collectors[i].enabled == flag_on && collectors[i]->init) {
-      argc = 0;
-      for (struct slist *arg = ctx->collectors[i].args; arg && argc < max_args; arg = arg->next)
-        argv[argc++] = arg->data;
-      argv[argc] = 0;
+  ctx->enabled = 0;
 
-      ctx->collectors[i].ctx = collectors[i]->init(argc, argv);
+  for (unsigned i = 0; i < NCOLLECTORS; i++) {
+    if (coll_enabled[i] != flag_on)
+      continue;
 
-      if (!ctx->collectors[i].ctx) {
+    unsigned c = ctx->enabled++;
+    ctx->coll[c] = collectors[i];
+
+    if (collectors[i]->init) {
+      coll_argc = 0;
+      for (struct slist *arg = coll_args[i].args; arg && coll_argc < max_args; arg = arg->next)
+        coll_argv[coll_argc++] = arg->data;
+      coll_argv[coll_argc] = 0;
+
+      ctx->coll_ctx[c] = collectors[i]->init(coll_argc, coll_argv);
+
+      if (!ctx->coll_ctx[c]) {
         fprintf(stderr, "failed to initialize collector %s\n", collectors[i]->name);
         return false;
       }
+    } else {
+      ctx->coll_ctx[c] = 0;
     }
   }
 
@@ -231,12 +243,3 @@ static bool daemonize(struct config *cfg) {
 
   return true;
 }
-
-static void handler(scrape_req *req, void *ctx_ptr) {
-  struct handler_ctx *ctx = ctx_ptr;
-
-  for (size_t c = 0; c < NCOLLECTORS; c++) {
-    if (ctx->collectors[c].enabled == flag_on)
-      collectors[c]->collect(req, ctx->collectors[c].ctx);
-  }
-}
diff --git a/meminfo.c b/meminfo.c
index 7c4439e..e9c283a 100644
--- a/meminfo.c
+++ b/meminfo.c
@@ -20,7 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 // size of input buffer for paths and lines
diff --git a/netdev.c b/netdev.c
index b8f20b6..7e8561e 100644
--- a/netdev.c
+++ b/netdev.c
@@ -21,7 +21,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 // size of input buffer for paths and lines
diff --git a/scrape.c b/scrape.c
index c86e853..f632e4e 100644
--- a/scrape.c
+++ b/scrape.c
@@ -110,7 +110,7 @@ scrape_server *scrape_listen(const char *port) {
   return srv;
 }
 
-void scrape_serve(scrape_server *srv, scrape_handler *handler, void *handler_ctx) {
+void scrape_serve(scrape_server *srv, unsigned ncoll, const struct collector *coll[], void *coll_ctx[]) {
   struct scrape_req req;
   req.buf = bbuf_alloc(BUF_INITIAL, BUF_MAX);
 
@@ -137,8 +137,10 @@ void scrape_serve(scrape_server *srv, scrape_handler *handler, void *handler_ctx
         continue;
       }
 
-      if (handle_http(&req))
-        handler(&req, handler_ctx);
+      if (handle_http(&req)) {
+        for (unsigned c = 0; c < ncoll; c++)
+          coll[c]->collect(&req, coll_ctx[c]);
+      }
       close(req.socket);
     }
   }
diff --git a/scrape.h b/scrape.h
index 25a1e68..0c93828 100644
--- a/scrape.h
+++ b/scrape.h
@@ -26,14 +26,19 @@ typedef struct scrape_server scrape_server;
 /** Opaque type to represent an ongoing scrape request. */
 typedef struct scrape_req scrape_req;
 
-/** Function type for a scrape server callback. */
-typedef void scrape_handler(scrape_req *req, void *ctx);
+/** Interface type for implementing a collector that can be scraped. */
+struct collector {
+  const char *name;
+  void (*collect)(scrape_req *req, void *ctx);
+  void *(*init)(int argc, char *argv[]);
+  bool has_args;
+};
 
 /** Sets up a scrape server listening at the given port. */
 scrape_server *scrape_listen(const char *port);
 
-/** Enters a loop serving scrape requests using the provided handler. */
-void scrape_serve(scrape_server *server, scrape_handler *handler, void *handler_ctx);
+/** Enters a loop serving scrape requests of the provided collectors. */
+void scrape_serve(scrape_server *server, unsigned ncoll, const struct collector *coll[], void *coll_ctx[]);
 
 /** Closes the scrape server sockets and frees any resources. */
 void scrape_close(scrape_server *server);
diff --git a/stat.c b/stat.c
index a5ac52a..a1ade85 100644
--- a/stat.c
+++ b/stat.c
@@ -18,7 +18,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 // size of input buffer for paths and lines
diff --git a/test/cpu_test.c b/test/cpu_test.c
index 4698236..7b9ed43 100644
--- a/test/cpu_test.c
+++ b/test/cpu_test.c
@@ -16,7 +16,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector cpu_collector;
 void cpu_test_override_tick(void *ctx, long tick);
diff --git a/test/diskstats_test.c b/test/diskstats_test.c
index e1f1456..e7b53ec 100644
--- a/test/diskstats_test.c
+++ b/test/diskstats_test.c
@@ -16,7 +16,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector diskstats_collector;
 
diff --git a/test/filesystem_test.c b/test/filesystem_test.c
index 15aaa88..f358984 100644
--- a/test/filesystem_test.c
+++ b/test/filesystem_test.c
@@ -20,7 +20,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector filesystem_collector;
 void filesystem_test_override_statvfs(void *ctx, int (*statvfs_func)(const char *path, struct statvfs *buf));
diff --git a/test/hwmon_test.c b/test/hwmon_test.c
index 0df510b..02ef490 100644
--- a/test/hwmon_test.c
+++ b/test/hwmon_test.c
@@ -16,7 +16,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector hwmon_collector;
 
diff --git a/test/meminfo_test.c b/test/meminfo_test.c
index 91b4102..4f9ea19 100644
--- a/test/meminfo_test.c
+++ b/test/meminfo_test.c
@@ -16,7 +16,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector meminfo_collector;
 
diff --git a/test/netdev_test.c b/test/netdev_test.c
index 5db1da6..3b5cf09 100644
--- a/test/netdev_test.c
+++ b/test/netdev_test.c
@@ -16,7 +16,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector netdev_collector;
 
diff --git a/test/stat_test.c b/test/stat_test.c
index 4dbe3a7..b980267 100644
--- a/test/stat_test.c
+++ b/test/stat_test.c
@@ -16,7 +16,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector stat_collector;
 
diff --git a/test/textfile_test.c b/test/textfile_test.c
index b2ee2ca..82aa44a 100644
--- a/test/textfile_test.c
+++ b/test/textfile_test.c
@@ -16,7 +16,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector textfile_collector;
 
diff --git a/test/uname_test.c b/test/uname_test.c
index 3a8390c..4bad7ac 100644
--- a/test/uname_test.c
+++ b/test/uname_test.c
@@ -19,7 +19,6 @@
 
 #include "harness.h"
 #include "mock_scrape.h"
-#include "../collector.h"
 
 extern const struct collector uname_collector;
 void uname_test_override_data(void *ctx, struct utsname *name);
diff --git a/textfile.c b/textfile.c
index 205d2c5..0a8d235 100644
--- a/textfile.c
+++ b/textfile.c
@@ -20,7 +20,7 @@
 #include <string.h>
 #include <sys/types.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 #define DEFAULT_DIR "/var/lib/prometheus/node-exporter"
diff --git a/uname.c b/uname.c
index a9e4ade..f1d49bb 100644
--- a/uname.c
+++ b/uname.c
@@ -18,7 +18,7 @@
 #include <stdlib.h>
 #include <sys/utsname.h>
 
-#include "collector.h"
+#include "scrape.h"
 #include "util.h"
 
 static void *uname_init(int argc, char *argv[]);