Merge pull request #2618 from ajssmith/amqp1_dev1_branch
[collectd.git] / src / varnish.c
index 41b60d8..b515be8 100644 (file)
@@ -21,6 +21,7 @@
  *   Jérôme Renard <jerome.renard at gmail.com>
  *   Marc Fournier <marc.fournier at camptocamp.com>
  *   Florian octo Forster <octo at collectd.org>
+ *   Denes Matetelki <dmatetelki at varnish-software.com>
  **/
 
 #include "collectd.h"
@@ -28,7 +29,7 @@
 #include "common.h"
 #include "plugin.h"
 
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
 #include <vapi/vsc.h>
 #include <vapi/vsm.h>
 typedef struct VSC_C_main c_varnish_stats_t;
@@ -49,42 +50,50 @@ typedef struct varnish_stats c_varnish_stats_t;
 struct user_config_s {
   char *instance;
 
-  _Bool collect_cache;
-  _Bool collect_connections;
-  _Bool collect_esi;
-  _Bool collect_backend;
+  bool collect_cache;
+  bool collect_connections;
+  bool collect_esi;
+  bool collect_backend;
 #ifdef HAVE_VARNISH_V3
-  _Bool collect_dirdns;
+  bool collect_dirdns;
 #endif
-  _Bool collect_fetch;
-  _Bool collect_hcb;
-  _Bool collect_objects;
+  bool collect_fetch;
+  bool collect_hcb;
+  bool collect_objects;
 #if HAVE_VARNISH_V2
-  _Bool collect_purge;
+  bool collect_purge;
 #else
-  _Bool collect_ban;
+  bool collect_ban;
 #endif
-  _Bool collect_session;
-  _Bool collect_shm;
-  _Bool collect_sms;
+  bool collect_session;
+  bool collect_shm;
+  bool collect_sms;
 #if HAVE_VARNISH_V2
-  _Bool collect_sm;
-  _Bool collect_sma;
+  bool collect_sm;
 #endif
-  _Bool collect_struct;
-  _Bool collect_totals;
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
-  _Bool collect_uptime;
+#if HAVE_VARNISH_V2 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+  bool collect_sma;
+#endif
+  bool collect_struct;
+  bool collect_totals;
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+  bool collect_uptime;
 #endif
-  _Bool collect_vcl;
-  _Bool collect_workers;
-#if HAVE_VARNISH_V4
-  _Bool collect_vsm;
+  bool collect_vcl;
+  bool collect_workers;
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+  bool collect_vsm;
+  bool collect_lck;
+  bool collect_mempool;
+  bool collect_mgt;
+  bool collect_smf;
+  bool collect_vbe;
+  bool collect_mse;
 #endif
 };
 typedef struct user_config_s user_config_t; /* }}} */
 
-static _Bool have_instance = 0;
+static bool have_instance;
 
 static int varnish_submit(const char *plugin_instance, /* {{{ */
                           const char *category, const char *type,
@@ -98,60 +107,70 @@ static int varnish_submit(const char *plugin_instance, /* {{{ */
 
   if (plugin_instance == NULL)
     plugin_instance = "default";
-  ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
-            plugin_instance, category);
+  snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
+           plugin_instance, category);
 
   sstrncpy(vl.type, type, sizeof(vl.type));
 
   if (type_instance != NULL)
     sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
 
-  return (plugin_dispatch_values(&vl));
+  return plugin_dispatch_values(&vl);
 } /* }}} int varnish_submit */
 
 static int varnish_submit_gauge(const char *plugin_instance, /* {{{ */
                                 const char *category, const char *type,
                                 const char *type_instance,
                                 uint64_t gauge_value) {
-  return (varnish_submit(plugin_instance, category, type, type_instance,
-                         (value_t){.gauge = (gauge_t)gauge_value}));
+  return varnish_submit(plugin_instance, category, type, type_instance,
+                        (value_t){
+                            .gauge = (gauge_t)gauge_value,
+                        });
 } /* }}} int varnish_submit_gauge */
 
 static int varnish_submit_derive(const char *plugin_instance, /* {{{ */
                                  const char *category, const char *type,
                                  const char *type_instance,
                                  uint64_t derive_value) {
-  return (varnish_submit(plugin_instance, category, type, type_instance,
-                         (value_t){.derive = (derive_t)derive_value}));
+  return varnish_submit(plugin_instance, category, type, type_instance,
+                        (value_t){
+                            .derive = (derive_t)derive_value,
+                        });
 } /* }}} int varnish_submit_derive */
 
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
 static int varnish_monitor(void *priv,
                            const struct VSC_point *const pt) /* {{{ */
 {
   uint64_t val;
   const user_config_t *conf;
-  const char *class;
   const char *name;
 
   if (pt == NULL)
-    return (0);
+    return 0;
 
   conf = priv;
 
-#if HAVE_VARNISH_V4
-  class = pt->section->fantom->type;
-  name = pt->desc->name;
+#if HAVE_VARNISH_V5
+  char namebuff[DATA_MAX_NAME_LEN];
 
-  if (strcmp(class, "MAIN") != 0)
-    return (0);
+  char const *c = strrchr(pt->name, '.');
+  if (c == NULL) {
+    return EINVAL;
+  }
+  sstrncpy(namebuff, c + 1, sizeof(namebuff));
+  name = namebuff;
+
+#elif HAVE_VARNISH_V4
+  if (strcmp(pt->section->fantom->type, "MAIN") != 0)
+    return 0;
 
+  name = pt->desc->name;
 #elif HAVE_VARNISH_V3
-  class = pt->class;
-  name = pt->name;
+  if (strcmp(pt->class, "") != 0)
+    return 0;
 
-  if (strcmp(class, "") != 0)
-    return (0);
+  name = pt->name;
 #endif
 
   val = *(const volatile uint64_t *)pt->ptr;
@@ -178,6 +197,14 @@ static int varnish_monitor(void *priv,
     else if (strcmp(name, "client_req") == 0)
       return varnish_submit_derive(conf->instance, "connections", "connections",
                                    "received", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+    else if (strcmp(name, "client_req_400") == 0)
+      return varnish_submit_derive(conf->instance, "connections", "connections",
+                                   "error_400", val);
+    else if (strcmp(name, "client_req_417") == 0)
+      return varnish_submit_derive(conf->instance, "connections", "connections",
+                                   "error_417", val);
+#endif
   }
 
 #ifdef HAVE_VARNISH_V3
@@ -207,6 +234,9 @@ static int varnish_monitor(void *priv,
     else if (strcmp(name, "esi_warnings") == 0)
       return varnish_submit_derive(conf->instance, "esi", "total_operations",
                                    "warning", val);
+    else if (strcmp(name, "esi_maxdepth") == 0)
+      return varnish_submit_derive(conf->instance, "esi", "total_operations",
+                                   "max_depth", val);
   }
 
   if (conf->collect_backend) {
@@ -282,6 +312,20 @@ static int varnish_monitor(void *priv,
     else if (strcmp(name, "fetch_304") == 0)
       return varnish_submit_derive(conf->instance, "fetch", "http_requests",
                                    "no_body_304", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+    else if (strcmp(name, "fetch_no_thread") == 0)
+      return varnish_submit_derive(conf->instance, "fetch", "http_requests",
+                                   "no_thread", val);
+    else if (strcmp(name, "fetch_none") == 0)
+      return varnish_submit_derive(conf->instance, "fetch", "http_requests",
+                                   "none", val);
+    else if (strcmp(name, "busy_sleep") == 0)
+      return varnish_submit_derive(conf->instance, "fetch", "http_requests",
+                                   "busy_sleep", val);
+    else if (strcmp(name, "busy_wakeup") == 0)
+      return varnish_submit_derive(conf->instance, "fetch", "http_requests",
+                                   "busy_wakeup", val);
+#endif
   }
 
   if (conf->collect_hcb) {
@@ -327,6 +371,14 @@ static int varnish_monitor(void *priv,
     else if (strcmp(name, "n_objoverflow") == 0)
       return varnish_submit_derive(conf->instance, "objects", "total_objects",
                                    "workspace_overflow", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+    else if (strcmp(name, "exp_mailed") == 0)
+      return varnish_submit_gauge(conf->instance, "struct", "objects",
+                                  "exp_mailed", val);
+    else if (strcmp(name, "exp_received") == 0)
+      return varnish_submit_gauge(conf->instance, "struct", "objects",
+                                  "exp_received", val);
+#endif
   }
 
 #if HAVE_VARNISH_V3
@@ -351,7 +403,7 @@ static int varnish_monitor(void *priv,
                                    "duplicate", val);
   }
 #endif
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
   if (conf->collect_ban) {
     if (strcmp(name, "bans") == 0)
       return varnish_submit_derive(conf->instance, "ban", "total_operations",
@@ -377,6 +429,33 @@ static int varnish_monitor(void *priv,
     else if (strcmp(name, "bans_dups") == 0)
       return varnish_submit_derive(conf->instance, "ban", "total_operations",
                                    "duplicate", val);
+    else if (strcmp(name, "bans_tested") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_operations",
+                                   "tested", val);
+    else if (strcmp(name, "bans_lurker_contention") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_operations",
+                                   "lurker_contention", val);
+    else if (strcmp(name, "bans_lurker_obj_killed") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_operations",
+                                   "lurker_obj_killed", val);
+    else if (strcmp(name, "bans_lurker_tested") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_operations",
+                                   "lurker_tested", val);
+    else if (strcmp(name, "bans_lurker_tests_tested") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_operations",
+                                   "lurker_tests_tested", val);
+    else if (strcmp(name, "bans_obj_killed") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_operations",
+                                   "obj_killed", val);
+    else if (strcmp(name, "bans_persisted_bytes") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_bytes",
+                                   "persisted_bytes", val);
+    else if (strcmp(name, "bans_persisted_fragmentation") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_bytes",
+                                   "persisted_fragmentation", val);
+    else if (strcmp(name, "bans_tests_tested") == 0)
+      return varnish_submit_derive(conf->instance, "ban", "total_operations",
+                                   "tests_tested", val);
   }
 #endif
 
@@ -411,6 +490,15 @@ static int varnish_monitor(void *priv,
     else if (strcmp(name, "sess_herd") == 0)
       return varnish_submit_derive(conf->instance, "session",
                                    "total_operations", "herd", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+    else if (strcmp(name, "sess_closed_err") == 0)
+      return varnish_submit_derive(conf->instance, "session",
+                                   "total_operations", "closed_err", val);
+    else if (strcmp(name, "sess_dropped") == 0)
+      return varnish_submit_derive(conf->instance, "session",
+                                   "total_operations", "dropped_for_thread",
+                                   val);
+#endif
   }
 
   if (conf->collect_shm) {
@@ -510,12 +598,18 @@ static int varnish_monitor(void *priv,
     else if (strcmp(name, "s_req_bodybytes") == 0)
       return varnish_submit_derive(conf->instance, "totals", "total_bytes",
                                    "req_body", val);
+    else if (strcmp(name, "s_req_protobytes") == 0)
+      return varnish_submit_derive(conf->instance, "totals", "total_bytes",
+                                   "req_proto", val);
     else if (strcmp(name, "s_resp_hdrbytes") == 0)
       return varnish_submit_derive(conf->instance, "totals", "total_bytes",
                                    "resp_header", val);
     else if (strcmp(name, "s_resp_bodybytes") == 0)
       return varnish_submit_derive(conf->instance, "totals", "total_bytes",
                                    "resp_body", val);
+    else if (strcmp(name, "s_resp_protobytes") == 0)
+      return varnish_submit_derive(conf->instance, "totals", "total_bytes",
+                                   "resp_proto", val);
     else if (strcmp(name, "s_pipe_hdrbytes") == 0)
       return varnish_submit_derive(conf->instance, "totals", "total_bytes",
                                    "pipe_header", val);
@@ -580,8 +674,8 @@ static int varnish_monitor(void *priv,
       return varnish_submit_derive(conf->instance, "workers", "total_threads",
                                    "dropped", val);
     else if (strcmp(name, "thread_queue_len") == 0)
-      return varnish_submit_derive(conf->instance, "workers", "queue_length",
-                                   "threads", val);
+      return varnish_submit_gauge(conf->instance, "workers", "queue_length",
+                                  "threads", val);
     else if (strcmp(name, "n_wrk") == 0)
       return varnish_submit_gauge(conf->instance, "workers", "threads",
                                   "worker", val);
@@ -609,9 +703,17 @@ static int varnish_monitor(void *priv,
     else if (strcmp(name, "n_wrk_lqueue") == 0)
       return varnish_submit_derive(conf->instance, "workers", "total_requests",
                                    "queue_length", val);
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+    else if (strcmp(name, "pools") == 0)
+      return varnish_submit_gauge(conf->instance, "workers", "pools", "pools",
+                                  val);
+    else if (strcmp(name, "busy_killed") == 0)
+      return varnish_submit_derive(conf->instance, "workers", "http_requests",
+                                   "busy_killed", val);
+#endif
   }
 
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
   if (conf->collect_vsm) {
     if (strcmp(name, "vsm_free") == 0)
       return varnish_submit_gauge(conf->instance, "vsm", "bytes", "free", val);
@@ -627,9 +729,262 @@ static int varnish_monitor(void *priv,
       return varnish_submit_derive(conf->instance, "vsm", "total_bytes",
                                    "overflowed", val);
   }
+
+  if (conf->collect_vbe) {
+    /* @TODO figure out the collectd type for bitmap
+    if (strcmp(name, "happy") == 0)
+      return varnish_submit_derive(conf->instance, "vbe",
+                                   "bitmap", "happy_hprobes", val);
+    */
+    if (strcmp(name, "bereq_hdrbytes") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "bereq_hdrbytes", val);
+    else if (strcmp(name, "bereq_bodybytes") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "bereq_bodybytes", val);
+    else if (strcmp(name, "bereq_protobytes") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "bereq_protobytes", val);
+    else if (strcmp(name, "beresp_hdrbytes") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "beresp_hdrbytes", val);
+    else if (strcmp(name, "beresp_bodybytes") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "beresp_bodybytes", val);
+    else if (strcmp(name, "beresp_protobytes") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "beresp_protobytes", val);
+    else if (strcmp(name, "pipe_hdrbytes") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "pipe_hdrbytes", val);
+    else if (strcmp(name, "pipe_out") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "pipe_out", val);
+    else if (strcmp(name, "pipe_in") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "total_bytes",
+                                   "pipe_in", val);
+    else if (strcmp(name, "conn") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "connections",
+                                   "c_conns", val);
+    else if (strcmp(name, "req") == 0)
+      return varnish_submit_derive(conf->instance, "vbe", "http_requests",
+                                   "b_reqs", val);
+  }
+
+  /* All Stevedores support these counters */
+  if (conf->collect_sma || conf->collect_smf || conf->collect_mse) {
+
+    char category[4];
+    if (conf->collect_sma)
+      strncpy(category, "sma", 4);
+    else if (conf->collect_smf)
+      strncpy(category, "smf", 4);
+    else
+      strncpy(category, "mse", 4);
+
+    if (strcmp(name, "c_req") == 0)
+      return varnish_submit_derive(conf->instance, category, "total_operations",
+                                   "alloc_req", val);
+    else if (strcmp(name, "c_fail") == 0)
+      return varnish_submit_derive(conf->instance, category, "total_operations",
+                                   "alloc_fail", val);
+    else if (strcmp(name, "c_bytes") == 0)
+      return varnish_submit_derive(conf->instance, category, "total_bytes",
+                                   "bytes_allocated", val);
+    else if (strcmp(name, "c_freed") == 0)
+      return varnish_submit_derive(conf->instance, category, "total_bytes",
+                                   "bytes_freed", val);
+    else if (strcmp(name, "g_alloc") == 0)
+      return varnish_submit_derive(conf->instance, category, "total_operations",
+                                   "alloc_outstanding", val);
+    else if (strcmp(name, "g_bytes") == 0)
+      return varnish_submit_gauge(conf->instance, category, "bytes",
+                                  "bytes_outstanding", val);
+    else if (strcmp(name, "g_space") == 0)
+      return varnish_submit_gauge(conf->instance, category, "bytes",
+                                  "bytes_available", val);
+  }
+
+  /* No SMA specific counters */
+
+  if (conf->collect_smf) {
+    if (strcmp(name, "g_smf") == 0)
+      return varnish_submit_gauge(conf->instance, "smf", "objects",
+                                  "n_struct_smf", val);
+    else if (strcmp(name, "g_smf_frag") == 0)
+      return varnish_submit_gauge(conf->instance, "smf", "objects",
+                                  "n_small_free_smf", val);
+    else if (strcmp(name, "g_smf_large") == 0)
+      return varnish_submit_gauge(conf->instance, "smf", "objects",
+                                  "n_large_free_smf", val);
+  }
+
+  if (conf->collect_mgt) {
+    if (strcmp(name, "uptime") == 0)
+      return varnish_submit_gauge(conf->instance, "mgt", "uptime",
+                                  "mgt_proc_uptime", val);
+    else if (strcmp(name, "child_start") == 0)
+      return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+                                   "child_start", val);
+    else if (strcmp(name, "child_exit") == 0)
+      return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+                                   "child_exit", val);
+    else if (strcmp(name, "child_stop") == 0)
+      return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+                                   "child_stop", val);
+    else if (strcmp(name, "child_died") == 0)
+      return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+                                   "child_died", val);
+    else if (strcmp(name, "child_dump") == 0)
+      return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+                                   "child_dump", val);
+    else if (strcmp(name, "child_panic") == 0)
+      return varnish_submit_derive(conf->instance, "mgt", "total_operations",
+                                   "child_panic", val);
+  }
+
+  if (conf->collect_lck) {
+    if (strcmp(name, "creat") == 0)
+      return varnish_submit_gauge(conf->instance, "lck", "objects", "created",
+                                  val);
+    else if (strcmp(name, "destroy") == 0)
+      return varnish_submit_gauge(conf->instance, "lck", "objects", "destroyed",
+                                  val);
+    else if (strcmp(name, "locks") == 0)
+      return varnish_submit_derive(conf->instance, "lck", "total_operations",
+                                   "lock_ops", val);
+  }
+
+  if (conf->collect_mempool) {
+    if (strcmp(name, "live") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "objects",
+                                  "in_use", val);
+    else if (strcmp(name, "pool") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "objects",
+                                  "in_pool", val);
+    else if (strcmp(name, "sz_wanted") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "bytes",
+                                  "size_requested", val);
+    else if (strcmp(name, "sz_actual") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "bytes",
+                                  "size_allocated", val);
+    else if (strcmp(name, "allocs") == 0)
+      return varnish_submit_derive(conf->instance, "mempool",
+                                   "total_operations", "allocations", val);
+    else if (strcmp(name, "frees") == 0)
+      return varnish_submit_derive(conf->instance, "mempool",
+                                   "total_operations", "frees", val);
+    else if (strcmp(name, "recycle") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "objects",
+                                  "recycled", val);
+    else if (strcmp(name, "timeout") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "objects",
+                                  "timed_out", val);
+    else if (strcmp(name, "toosmall") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "objects",
+                                  "too_small", val);
+    else if (strcmp(name, "surplus") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "objects",
+                                  "surplus", val);
+    else if (strcmp(name, "randry") == 0)
+      return varnish_submit_gauge(conf->instance, "mempool", "objects",
+                                  "ran_dry", val);
+  }
+
+  if (conf->collect_mse) {
+    if (strcmp(name, "c_full") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_operations",
+                                   "full_allocs", val);
+    else if (strcmp(name, "c_truncated") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_operations",
+                                   "truncated_allocs", val);
+    else if (strcmp(name, "c_expanded") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_operations",
+                                   "expanded_allocs", val);
+    else if (strcmp(name, "c_failed") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_operations",
+                                   "failed_allocs", val);
+    else if (strcmp(name, "c_bytes") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_bytes",
+                                   "bytes_allocated", val);
+    else if (strcmp(name, "c_freed") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_bytes",
+                                   "bytes_freed", val);
+    else if (strcmp(name, "g_fo_alloc") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_operations",
+                                   "fo_allocs_outstanding", val);
+    else if (strcmp(name, "g_fo_bytes") == 0)
+      return varnish_submit_gauge(conf->instance, "mse", "bytes",
+                                  "fo_bytes_outstanding", val);
+    else if (strcmp(name, "g_membuf_alloc") == 0)
+      return varnish_submit_gauge(conf->instance, "mse", "objects",
+                                  "membufs_allocated", val);
+    else if (strcmp(name, "g_membuf_inuse") == 0)
+      return varnish_submit_gauge(conf->instance, "mse", "objects",
+                                  "membufs_inuse", val);
+    else if (strcmp(name, "g_bans_bytes") == 0)
+      return varnish_submit_gauge(conf->instance, "mse", "bytes",
+                                  "persisted_banspace_used", val);
+    else if (strcmp(name, "g_bans_space") == 0)
+      return varnish_submit_gauge(conf->instance, "mse", "bytes",
+                                  "persisted_banspace_available", val);
+    else if (strcmp(name, "g_bans_persisted") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_operations",
+                                   "bans_persisted", val);
+    else if (strcmp(name, "g_bans_lost") == 0)
+      return varnish_submit_derive(conf->instance, "mse", "total_operations",
+                                   "bans_lost", val);
+
+    /* mse seg */
+    else if (strcmp(name, "g_journal_bytes") == 0)
+      return varnish_submit_gauge(conf->instance, "mse_reg", "bytes",
+                                  "journal_bytes_used", val);
+    else if (strcmp(name, "g_journal_space") == 0)
+      return varnish_submit_gauge(conf->instance, "mse_reg", "bytes",
+                                  "journal_bytes_free", val);
+
+    /* mse segagg */
+    else if (strcmp(name, "g_bigspace") == 0)
+      return varnish_submit_gauge(conf->instance, "mse_segagg", "bytes",
+                                  "big_extents_bytes_available", val);
+    else if (strcmp(name, "g_extfree") == 0)
+      return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+                                  "free_extents", val);
+    else if (strcmp(name, "g_sparenode") == 0)
+      return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+                                  "spare_nodes_available", val);
+    else if (strcmp(name, "g_objnode") == 0)
+      return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+                                  "object_nodes_in_use", val);
+    else if (strcmp(name, "g_extnode") == 0)
+      return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+                                  "extent_nodes_in_use", val);
+    else if (strcmp(name, "g_bigextfree") == 0)
+      return varnish_submit_gauge(conf->instance, "mse_segagg", "objects",
+                                  "free_big_extents", val);
+    else if (strcmp(name, "c_pruneloop") == 0)
+      return varnish_submit_derive(conf->instance, "mse_segagg",
+                                   "total_operations", "prune_loops", val);
+    else if (strcmp(name, "c_pruned") == 0)
+      return varnish_submit_derive(conf->instance, "mse_segagg",
+                                   "total_objects", "pruned_objects", val);
+    else if (strcmp(name, "c_spared") == 0)
+      return varnish_submit_derive(conf->instance, "mse_segagg",
+                                   "total_operations", "spared_objects", val);
+    else if (strcmp(name, "c_skipped") == 0)
+      return varnish_submit_derive(conf->instance, "mse_segagg",
+                                   "total_operations", "missed_objects", val);
+    else if (strcmp(name, "c_nuked") == 0)
+      return varnish_submit_derive(conf->instance, "mse_segagg",
+                                   "total_operations", "nuked_objects", val);
+    else if (strcmp(name, "c_sniped") == 0)
+      return varnish_submit_derive(conf->instance, "mse_segagg",
+                                   "total_operations", "sniped_objects", val);
+  }
+
 #endif
 
-  return (0);
+  return 0;
 
 } /* }}} static int varnish_monitor */
 #else /* if HAVE_VARNISH_V2 */
@@ -971,21 +1326,32 @@ static void varnish_monitor(const user_config_t *conf, /* {{{ */
 } /* }}} void varnish_monitor */
 #endif
 
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
 static int varnish_read(user_data_t *ud) /* {{{ */
 {
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
   struct VSM_data *vd;
+  bool ok;
   const c_varnish_stats_t *stats;
-  _Bool ok;
+#elif HAVE_VARNISH_V5
+  struct vsm *vd;
+  struct vsc *vsc;
+  int vsm_status;
+#endif
 
   user_config_t *conf;
 
   if ((ud == NULL) || (ud->data == NULL))
-    return (EINVAL);
+    return EINVAL;
 
   conf = ud->data;
 
   vd = VSM_New();
+
+#if HAVE_VARNISH_V5
+  vsc = VSC_New();
+#endif
+
 #if HAVE_VARNISH_V3
   VSC_Setup(vd);
 #endif
@@ -993,48 +1359,85 @@ static int varnish_read(user_data_t *ud) /* {{{ */
   if (conf->instance != NULL) {
     int status;
 
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
     status = VSM_n_Arg(vd, conf->instance);
+#elif HAVE_VARNISH_V5
+    status = VSM_Arg(vd, 'n', conf->instance);
+#endif
+
     if (status < 0) {
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
       VSM_Delete(vd);
-      ERROR("varnish plugin: VSM_n_Arg (\"%s\") failed "
+#elif HAVE_VARNISH_V5
+      VSC_Destroy(&vsc, vd);
+      VSM_Destroy(&vd);
+#endif
+      ERROR("varnish plugin: VSM_Arg (\"%s\") failed "
             "with status %i.",
             conf->instance, status);
-      return (-1);
+      return -1;
     }
   }
 
 #if HAVE_VARNISH_V3
   ok = (VSC_Open(vd, /* diag = */ 1) == 0);
-#else /* if HAVE_VARNISH_V4 */
+#elif HAVE_VARNISH_V4
   ok = (VSM_Open(vd) == 0);
 #endif
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
   if (!ok) {
     VSM_Delete(vd);
     ERROR("varnish plugin: Unable to open connection.");
-
-    return (-1);
+    return -1;
   }
+#endif
 
 #if HAVE_VARNISH_V3
   stats = VSC_Main(vd);
-#else /* if HAVE_VARNISH_V4 */
+#elif HAVE_VARNISH_V4
   stats = VSC_Main(vd, NULL);
 #endif
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
   if (!stats) {
     VSM_Delete(vd);
     ERROR("varnish plugin: Unable to get statistics.");
+    return -1;
+  }
+#endif
+
+#if HAVE_VARNISH_V5
+  if (VSM_Attach(vd, STDERR_FILENO)) {
+    ERROR("varnish plugin: Cannot attach to varnish. %s", VSM_Error(vd));
+    VSC_Destroy(&vsc, vd);
+    VSM_Destroy(&vd);
+    return -1;
+  }
 
-    return (-1);
+  vsm_status = VSM_Status(vd);
+  if (vsm_status & ~(VSM_MGT_RUNNING | VSM_WRK_RUNNING)) {
+    ERROR("varnish plugin: Unable to get statistics.");
+    VSC_Destroy(&vsc, vd);
+    VSM_Destroy(&vd);
+    return -1;
   }
+#endif
 
 #if HAVE_VARNISH_V3
   VSC_Iter(vd, varnish_monitor, conf);
-#else /* if HAVE_VARNISH_V4 */
+#elif HAVE_VARNISH_V4
   VSC_Iter(vd, NULL, varnish_monitor, conf);
+#elif HAVE_VARNISH_V5
+  VSC_Iter(vsc, vd, varnish_monitor, conf);
 #endif
+
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
   VSM_Delete(vd);
+#elif HAVE_VARNISH_V5
+  VSC_Destroy(&vsc, vd);
+  VSM_Destroy(&vd);
+#endif
 
-  return (0);
+  return 0;
 } /* }}} */
 #else /* if HAVE_VARNISH_V2 */
 static int varnish_read(user_data_t *ud) /* {{{ */
@@ -1044,7 +1447,7 @@ static int varnish_read(user_data_t *ud) /* {{{ */
   user_config_t *conf;
 
   if ((ud == NULL) || (ud->data == NULL))
-    return (EINVAL);
+    return EINVAL;
 
   conf = ud->data;
 
@@ -1052,12 +1455,12 @@ static int varnish_read(user_data_t *ud) /* {{{ */
   if (stats == NULL) {
     ERROR("Varnish plugin : unable to load statistics");
 
-    return (-1);
+    return -1;
   }
 
   varnish_monitor(conf, stats);
 
-  return (0);
+  return 0;
 } /* }}} */
 #endif
 
@@ -1075,42 +1478,50 @@ static void varnish_config_free(void *ptr) /* {{{ */
 static int varnish_config_apply_default(user_config_t *conf) /* {{{ */
 {
   if (conf == NULL)
-    return (EINVAL);
+    return EINVAL;
 
-  conf->collect_backend = 1;
-  conf->collect_cache = 1;
-  conf->collect_connections = 1;
+  conf->collect_backend = true;
+  conf->collect_cache = true;
+  conf->collect_connections = true;
 #ifdef HAVE_VARNISH_V3
-  conf->collect_dirdns = 0;
+  conf->collect_dirdns = false;
 #endif
-  conf->collect_esi = 0;
-  conf->collect_fetch = 0;
-  conf->collect_hcb = 0;
-  conf->collect_objects = 0;
+  conf->collect_esi = false;
+  conf->collect_fetch = false;
+  conf->collect_hcb = false;
+  conf->collect_objects = false;
 #if HAVE_VARNISH_V2
-  conf->collect_purge = 0;
+  conf->collect_purge = false;
 #else
-  conf->collect_ban = 0;
+  conf->collect_ban = false;
 #endif
-  conf->collect_session = 0;
-  conf->collect_shm = 1;
+  conf->collect_session = false;
+  conf->collect_shm = true;
 #if HAVE_VARNISH_V2
-  conf->collect_sm = 0;
-  conf->collect_sma = 0;
+  conf->collect_sm = false;
 #endif
-  conf->collect_sms = 0;
-  conf->collect_struct = 0;
-  conf->collect_totals = 0;
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
-  conf->collect_uptime = 0;
+#if HAVE_VARNISH_V2 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+  conf->collect_sma = false;
+#endif
+  conf->collect_sms = false;
+  conf->collect_struct = false;
+  conf->collect_totals = false;
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+  conf->collect_uptime = false;
 #endif
-  conf->collect_vcl = 0;
-  conf->collect_workers = 0;
-#if HAVE_VARNISH_V4
-  conf->collect_vsm = 0;
+  conf->collect_vcl = false;
+  conf->collect_workers = false;
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+  conf->collect_vsm = false;
+  conf->collect_lck = false;
+  conf->collect_mempool = false;
+  conf->collect_mgt = false;
+  conf->collect_smf = false;
+  conf->collect_vbe = false;
+  conf->collect_mse = false;
 #endif
 
-  return (0);
+  return 0;
 } /* }}} int varnish_config_apply_default */
 
 static int varnish_init(void) /* {{{ */
@@ -1118,11 +1529,11 @@ static int varnish_init(void) /* {{{ */
   user_config_t *conf;
 
   if (have_instance)
-    return (0);
+    return 0;
 
   conf = calloc(1, sizeof(*conf));
   if (conf == NULL)
-    return (ENOMEM);
+    return ENOMEM;
 
   /* Default settings: */
   conf->instance = NULL;
@@ -1133,11 +1544,12 @@ static int varnish_init(void) /* {{{ */
       /* group = */ "varnish",
       /* name      = */ "varnish/localhost",
       /* callback  = */ varnish_read,
-      /* interval  = */ 0, &(user_data_t){
-                               .data = conf, .free_func = varnish_config_free,
-                           });
+      /* interval  = */ 0,
+      &(user_data_t){
+          .data = conf, .free_func = varnish_config_free,
+      });
 
-  return (0);
+  return 0;
 } /* }}} int varnish_init */
 
 static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
@@ -1147,7 +1559,7 @@ static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
 
   conf = calloc(1, sizeof(*conf));
   if (conf == NULL)
-    return (ENOMEM);
+    return ENOMEM;
   conf->instance = NULL;
 
   varnish_config_apply_default(conf);
@@ -1158,7 +1570,7 @@ static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
     status = cf_util_get_string(ci, &conf->instance);
     if (status != 0) {
       sfree(conf);
-      return (status);
+      return status;
     }
     assert(conf->instance != NULL);
 
@@ -1170,7 +1582,7 @@ static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
     WARNING("Varnish plugin: \"Instance\" blocks accept only "
             "one argument.");
     sfree(conf);
-    return (EINVAL);
+    return EINVAL;
   }
 
   for (int i = 0; i < ci->children_num; i++) {
@@ -1218,11 +1630,11 @@ static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
     else if (strcasecmp("CollectSMS", child->key) == 0)
       cf_util_get_boolean(child, &conf->collect_sms);
     else if (strcasecmp("CollectSMA", child->key) == 0)
-#if HAVE_VARNISH_V2
+#if HAVE_VARNISH_V2 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
       cf_util_get_boolean(child, &conf->collect_sma);
 #else
       WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
-              child->key, "v2");
+              child->key, "v2 and v4");
 #endif
     else if (strcasecmp("CollectSM", child->key) == 0)
 #if HAVE_VARNISH_V2
@@ -1236,7 +1648,7 @@ static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
     else if (strcasecmp("CollectTotals", child->key) == 0)
       cf_util_get_boolean(child, &conf->collect_totals);
     else if (strcasecmp("CollectUptime", child->key) == 0)
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
       cf_util_get_boolean(child, &conf->collect_uptime);
 #else
       WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
@@ -1247,12 +1659,61 @@ static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
     else if (strcasecmp("CollectWorkers", child->key) == 0)
       cf_util_get_boolean(child, &conf->collect_workers);
     else if (strcasecmp("CollectVSM", child->key) == 0)
-#if HAVE_VARNISH_V4
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
       cf_util_get_boolean(child, &conf->collect_vsm);
 #else
       WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
               child->key, "v4");
 #endif
+    else if (strcasecmp("CollectLock", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      cf_util_get_boolean(child, &conf->collect_lck);
+#else
+      WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+              child->key, "v4");
+#endif
+    else if (strcasecmp("CollectMempool", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      cf_util_get_boolean(child, &conf->collect_mempool);
+#else
+      WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+              child->key, "v4");
+#endif
+    else if (strcasecmp("CollectManagement", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      cf_util_get_boolean(child, &conf->collect_mgt);
+#else
+      WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+              child->key, "v4");
+#endif
+    else if (strcasecmp("CollectSMF", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      cf_util_get_boolean(child, &conf->collect_smf);
+#else
+      WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+              child->key, "v4");
+#endif
+    else if (strcasecmp("CollectSMF", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      cf_util_get_boolean(child, &conf->collect_smf);
+#else
+      WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+              child->key, "v4");
+#endif
+    else if (strcasecmp("CollectVBE", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      cf_util_get_boolean(child, &conf->collect_vbe);
+#else
+      WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+              child->key, "v4");
+#endif
+    else if (strcasecmp("CollectMSE", child->key) == 0)
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      cf_util_get_boolean(child, &conf->collect_mse);
+#else
+      WARNING("Varnish plugin: \"%s\" is available for Varnish %s only.",
+              child->key, "Plus v4");
+#endif
     else {
       WARNING("Varnish plugin: Ignoring unknown "
               "configuration option: \"%s\". Did "
@@ -1275,38 +1736,44 @@ static int varnish_config_instance(const oconfig_item_t *ci) /* {{{ */
 #endif
       && !conf->collect_session && !conf->collect_shm && !conf->collect_sms
 #if HAVE_VARNISH_V2
-      && !conf->collect_sma && !conf->collect_sm
+      && !conf->collect_sm
+#endif
+#if HAVE_VARNISH_V2 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      && !conf->collect_sma
 #endif
       && !conf->collect_struct && !conf->collect_totals
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4 || HAVE_VARNISH_V5
       && !conf->collect_uptime
 #endif
       && !conf->collect_vcl && !conf->collect_workers
-#if HAVE_VARNISH_V4
-      && !conf->collect_vsm
+#if HAVE_VARNISH_V4 || HAVE_VARNISH_V5
+      && !conf->collect_vsm && !conf->collect_vbe && !conf->collect_smf &&
+      !conf->collect_mgt && !conf->collect_lck && !conf->collect_mempool &&
+      !conf->collect_mse
 #endif
       ) {
     WARNING("Varnish plugin: No metric has been configured for "
             "instance \"%s\". Disabling this instance.",
             (conf->instance == NULL) ? "localhost" : conf->instance);
     sfree(conf);
-    return (EINVAL);
+    return EINVAL;
   }
 
-  ssnprintf(callback_name, sizeof(callback_name), "varnish/%s",
-            (conf->instance == NULL) ? "localhost" : conf->instance);
+  snprintf(callback_name, sizeof(callback_name), "varnish/%s",
+           (conf->instance == NULL) ? "localhost" : conf->instance);
 
   plugin_register_complex_read(
       /* group = */ "varnish",
       /* name      = */ callback_name,
       /* callback  = */ varnish_read,
-      /* interval  = */ 0, &(user_data_t){
-                               .data = conf, .free_func = varnish_config_free,
-                           });
+      /* interval  = */ 0,
+      &(user_data_t){
+          .data = conf, .free_func = varnish_config_free,
+      });
 
-  have_instance = 1;
+  have_instance = true;
 
-  return (0);
+  return 0;
 } /* }}} int varnish_config_instance */
 
 static int varnish_config(oconfig_item_t *ci) /* {{{ */
@@ -1323,7 +1790,7 @@ static int varnish_config(oconfig_item_t *ci) /* {{{ */
     }
   }
 
-  return (0);
+  return 0;
 } /* }}} int varnish_config */
 
 void module_register(void) /* {{{ */
@@ -1331,5 +1798,3 @@ void module_register(void) /* {{{ */
   plugin_register_complex_config("varnish", varnish_config);
   plugin_register_init("varnish", varnish_init);
 } /* }}} */
-
-/* vim: set sw=8 noet fdm=marker : */