about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHeikki Kallasjoki <fis@zem.fi>2018-12-04 13:12:04 +0000
committerHeikki Kallasjoki <fis@zem.fi>2018-12-04 13:12:04 +0000
commit0e9219a221201949cd0df937bea07355b6d4240b (patch)
tree4343e4b2c90947c76bac911b657f8bcedc95ddb6
parent11766041777085ef2746aedda66bf9483a7f1892 (diff)
downloadnano-exporter-0e9219a221201949cd0df937bea07355b6d4240b.tar.gz
nano-exporter-0e9219a221201949cd0df937bea07355b6d4240b.tar.xz
nano-exporter-0e9219a221201949cd0df937bea07355b6d4240b.zip
Add the stat collector.
-rw-r--r--Makefile1
-rw-r--r--README.md12
-rw-r--r--main.c2
-rw-r--r--stat.c79
4 files changed, 93 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index 90dece4..e770d0d 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,7 @@ COLLECTORS += filesystem
 COLLECTORS += hwmon
 COLLECTORS += meminfo
 COLLECTORS += network
+COLLECTORS += stat
 COLLECTORS += textfile
 COLLECTORS += uname
 
diff --git a/README.md b/README.md
index abb2cc0..55b66ce 100644
--- a/README.md
+++ b/README.md
@@ -58,6 +58,7 @@ including generated metrics, labels and configuration options.
 | [`hwmon`](#hwmon) | Temperature, fan and voltage sensors from `/sys/class/hwmon`. |
 | [`meminfo`](#meminfo) | Memory usage statistics from `/proc/meminfo`. |
 | [`network`](#network) | Network device transmit/receive statistics from `/proc/net/dev`. |
+| [`stat`](#stat) | Basic statistics from `/proc/stat`. |
 | [`textfile`](#textfile) | Custom metrics from `.prom` text files dropped in a directory. |
 | [`uname`](#uname) | Node information returned by the `uname` system call. |
 
@@ -265,6 +266,17 @@ list are included. If the given value ends in `*`, it matches any
 string that begins with the part before the `*`; otherwise, the match
 must be exact.
 
+### `stat`
+
+This collectors exports the following metrics from `/proc/stat`:
+
+* `node_boot_time_seconds`: System boot time as a Unix timestamp (seconds since 1970).
+* `node_context_switches_total`: Total number of context switches done by the system.
+* `node_forks_total`: Total number of forks since boot.
+* `node_intr_total`: Total number of interrupts serviced.
+* `node_procs_blocked`: Number of processes currently blocked for I/O.
+* `node_procs_running`: Number of processes currently in runnable state.
+
 ### `textfile`
 
 The `textfile` collector can be used to conveniently export custom
diff --git a/main.c b/main.c
index 3670a65..ee20463 100644
--- a/main.c
+++ b/main.c
@@ -32,7 +32,7 @@
 #ifndef XCOLLECTORS
 #define XCOLLECTORS \
   X(cpu) X(diskstats) X(filesystem) X(hwmon) \
-  X(meminfo) X(network) X(textfile) X(uname)
+  X(meminfo) X(network) X(stat) X(textfile) X(uname)
 #endif
 
 #define X(c) extern const struct collector c##_collector;
diff --git a/stat.c b/stat.c
new file mode 100644
index 0000000..e36579d
--- /dev/null
+++ b/stat.c
@@ -0,0 +1,79 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "collector.h"
+#include "util.h"
+
+// size of input buffer for paths and lines
+#define BUF_SIZE 256
+
+static void stat_collect(scrape_req *req, void *ctx);
+
+const struct collector stat_collector = {
+  .name = "stat",
+  .collect = stat_collect,
+};
+
+static const struct {
+  const char *name;
+  const char *key;
+  unsigned key_len;
+} metrics[] = {
+  { .name = "node_boot_time_seconds", .key = "btime ", .key_len = 6 },
+  { .name = "node_context_switches_total", .key = "ctxt ", .key_len = 5 },
+  { .name = "node_forks_total", .key = "processes ", .key_len = 10 },
+  { .name = "node_intr_total", .key = "intr ", .key_len = 5 },
+  { .name = "node_procs_blocked", .key = "procs_blocked ", .key_len = 14 },
+  { .name = "node_procs_running", .key = "procs_running ", .key_len = 14 },
+};
+#define NMETRICS (sizeof metrics / sizeof *metrics)
+
+static void stat_collect(scrape_req *req, void *ctx) {
+  (void) ctx;
+
+  // buffers
+
+  char buf[BUF_SIZE];
+
+  FILE *f;
+
+  // scan /proc/stat for metrics
+
+  f = fopen("/proc/stat", "r");
+  if (!f)
+    return;
+
+  while (fgets_line(buf, sizeof buf, f)) {
+    for (size_t m = 0; m < NMETRICS; m++) {
+      if (strncmp(buf, metrics[m].key, metrics[m].key_len) != 0)
+        continue;
+
+      char *end;
+      double d = strtod(buf + metrics[m].key_len, &end);
+      if (*end != '\0' && *end != ' ' && *end != '\n')
+        continue;
+
+      scrape_write(req, metrics[m].name, 0, d);
+      break;
+    }
+  }
+
+  fclose(f);
+}