@cryptotaxi247 / netdata-1 / commits / b3f690e7c

Add xenstat plugin (#5660)

* Add xenstat plugin * Add basic domain charts * Initialize xl context * Use domain UUID instead of name * Make charts obsolete * Add tmem charts * Change algorithm for tmem puts and gets * Add VCPU charts * Minor formatting for sending charts functions * Add VBD charts * Add network charts * Assemble VCPU metrics in one chart * Fix chart names * Make write/sent dimensions negative * Minor formatting * Change id and context for domain charts * Add dashboard info * Get rid of global variables * Free libxenstat and libxl resourses * Free domain_metrics on VM shutdown * Add domain state chart * Add debug messages * Add branch prediction hints * Minor fix * Fix chart obsoleting * Make names more general * Fix CMake build of nfacct.plugin

Vladimir Kobal committed Mar 27, 2019 at 11:19 UTC b3f690e7c9a759ef3a267766f228c0bcbfc02f4a
14 files changed +1438 -16
.gitignore
+3
@@ -53,6 +53,9 @@ cups.plugin
53 nfacct.plugin
54 !nfacct.plugin/
55
56 +xenstat.plugin
57 +!xenstat.plugin/
58 +
59 cgroup-network
60 !cgroup-network/
61
CMakeLists.txt
+34
@@ -135,6 +135,16 @@ pkg_check_modules(NFACCT libnetfilter_acct)
135 # ${NFACCT_INCLUDE_DIRS}
136
137
138 +# -----------------------------------------------------------------------------
139 +# Detect libxenstat
140 +
141 +pkg_check_modules(XENSTAT libxenstat)
142 +# later we use:
143 +# ${XENSTAT_LIBRARIES}
144 +# ${XENSTAT_CFLAGS_OTHER}
145 +# ${XENSTAT_INCLUDE_DIRS}
146 +
147 +
148 # -----------------------------------------------------------------------------
149 # Detect MacOS IOKit/Foundation framework
150
@@ -250,6 +260,10 @@ set(NFACCT_PLUGIN_FILES
260 collectors/nfacct.plugin/plugin_nfacct.c
261 )
262
263 +set(XENSTAT_PLUGIN_FILES
264 + collectors/xenstat.plugin/xenstat_plugin.c
265 + )
266 +
267 set(PROC_PLUGIN_FILES
268 collectors/proc.plugin/ipc.c
269 collectors/proc.plugin/plugin_proc.c
@@ -520,6 +534,12 @@ ELSE()
534 SET(ENABLE_PLUGIN_NFACCT False)
535 ENDIF()
536
537 +IF(XENSTAT_LIBRARIES)
538 + SET(ENABLE_PLUGIN_XENSTAT True)
539 +ELSE()
540 + SET(ENABLE_PLUGIN_XENSTAT False)
541 +ENDIF()
542 +
543
544 # -----------------------------------------------------------------------------
545 # apps.plugin
@@ -563,6 +583,20 @@ ELSE()
583 ENDIF()
584
585
586 +# -----------------------------------------------------------------------------
587 +# xenstat.plugin
588 +
589 +IF(ENABLE_PLUGIN_XENSTAT)
590 + message(STATUS "xenstat.plugin: enabled")
591 + add_executable(xenstat.plugin config.h ${XENSTAT_PLUGIN_FILES})
592 + target_link_libraries (xenstat.plugin libnetdata ${NETDATA_COMMON_LIBRARIES} ${XENSTAT_LIBRARIES})
593 + target_include_directories(xenstat.plugin PUBLIC ${NETDATA_COMMON_INCLUDE_DIRS} ${XENSTAT_INCLUDE_DIRS})
594 + target_compile_options(xenstat.plugin PUBLIC ${NETDATA_COMMON_CFLAGS} ${XENSTAT_CFLAGS_OTHER})
595 +ELSE()
596 + message(STATUS "xenstat.plugin: disabled (requires libxenstat)")
597 +ENDIF()
598 +
599 +
600 # -----------------------------------------------------------------------------
601 # cgroup-network
602
Makefile.am
+15
@@ -109,6 +109,7 @@ AM_CFLAGS = \
109 $(OPTIONAL_LIBCAP_LIBS) \
110 $(OPTIONAL_IPMIMONITORING_CFLAGS) \
111 $(OPTIONAL_CUPS_CFLAGS) \
112 + $(OPTIONAL_XENSTAT_CFLAGS) \
113 $(NULL)
114
115 sbin_PROGRAMS =
@@ -226,6 +227,11 @@ NFACCT_PLUGIN_FILES = \
227 $(LIBNETDATA_FILES) \
228 $(NULL)
229
230 +XENSTAT_PLUGIN_FILES = \
231 + collectors/xenstat.plugin/xenstat_plugin.c \
232 + $(LIBNETDATA_FILES) \
233 + $(NULL)
234 +
235 PROC_PLUGIN_FILES = \
236 collectors/proc.plugin/ipc.c \
237 collectors/proc.plugin/plugin_proc.c \
@@ -513,3 +519,12 @@ if ENABLE_PLUGIN_NFACCT
519 $(OPTIONAL_NFACCT_LIBS) \
520 $(NULL)
521 endif
522 +
523 +if ENABLE_PLUGIN_XENSTAT
524 + plugins_PROGRAMS += xenstat.plugin
525 + xenstat_plugin_SOURCES = $(XENSTAT_PLUGIN_FILES)
526 + xenstat_plugin_LDADD = \
527 + $(NETDATA_COMMON_LIBS) \
528 + $(OPTIONAL_XENSTAT_LIBS) \
529 + $(NULL)
530 +endif
collectors/README.md
+1
@@ -35,6 +35,7 @@ plugin|lang|O/S|runs as|modular|description
35 [idlejitter.plugin](idlejitter.plugin/)|`C`|any|internal|-|measures CPU latency and jitter on all operating systems
36 [macos.plugin](macos.plugin/)|`C`|macos|internal|yes|collects resource usage and performance data on MacOS systems
37 [nfacct.plugin](nfacct.plugin/)|`C`|linux|external|-|collects netfilter firewall, connection tracker and accounting metrics using `libmnl` and `libnetfilter_acct`
38 +[xenstat.plugin](xenstat.plugin/)|`C`|linux|external|-|collects XenServer and XCP-ng metrics using `libxenstat`
39 [node.d.plugin](node.d.plugin/)|`node.js`|any|external|yes|a **plugin orchestrator** for data collection modules written in `node.js`.
40 [plugins.d](plugins.d/)|`C`|any|internal|-|implements the **external plugins** API and serves external plugins
41 [proc.plugin](proc.plugin/)|`C`|linux|internal|yes|collects resource usage and performance data on Linux systems
collectors/apps.plugin/apps_groups.conf
+1
@@ -76,6 +76,7 @@ apps.plugin: apps.plugin
76 freeipmi.plugin: freeipmi.plugin
77 nfacct.plugin: nfacct.plugin
78 cups.plugin: cups.plugin
79 +xenstat.plugin: xenstat.plugin
80 charts.d.plugin: *charts.d.plugin*
81 node.d.plugin: *node.d.plugin*
82 python.d.plugin: *python.d.plugin*
collectors/plugins.d/README.md
+1
@@ -13,6 +13,7 @@ plugin|language|O/S|description
13 [fping.plugin](../fping.plugin/)|`C`|all|measures network latency, jitter and packet loss between the monitored node and any number of remote network end points.
14 [freeipmi.plugin](../freeipmi.plugin/)|`C`|linux|collects metrics from enterprise hardware sensors, on Linux servers.
15 [nfacct.plugin](../nfacct.plugin/)|`C`|linux|collects netfilter firewall, connection tracker and accounting metrics using `libmnl` and `libnetfilter_acct`.
16 +[xenstat.plugin](../xenstat.plugin/)|`C`|linux|collects XenServer and XCP-ng metrics using `lxenstat`.
17 [node.d.plugin](../node.d.plugin/)|`node.js`|all|a **plugin orchestrator** for data collection modules written in `node.js`.
18 [python.d.plugin](../python.d.plugin/)|`python`|all|a **plugin orchestrator** for data collection modules written in `python` v2 or v3 (both are supported).
19
collectors/xenstat.plugin/Makefile.am new
+8
@@ -0,0 +1,8 @@
1 +# SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +AUTOMAKE_OPTIONS = subdir-objects
4 +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
5 +
6 +dist_noinst_DATA = \
7 + README.md \
8 + $(NULL)
collectors/xenstat.plugin/README.md new
+45
@@ -0,0 +1,45 @@
1 +# xenstat.plugin
2 +
3 +`xenstat.plugin` collects XenServer and XCP-ng statistics.
4 +
5 +## Prerequisites
6 +
7 +1. install `xen-dom0-libs-devel` and `yajl-devel` using the package manager of your system.
8 +
9 +2. re-install netdata from source. The installer will detect that the required libraries are now available and will also build xenstat.plugin.
10 +
11 +Keep in mind that `libxenstat` requires root access, so the plugin is setuid to root.
12 +
13 +## Charts
14 +
15 +The plugin provides XenServer and XCP-ng host and domains statistics:
16 +
17 +Host:
18 +1. Number of domains.
19 +
20 +Domain:
21 +1. CPU.
22 +2. Memory.
23 +3. Networks.
24 +4. VBDs.
25 +
26 +## Configuration
27 +
28 +If you need to disable xenstat for netdata, edit /etc/netdata/netdata.conf and set:
29 +
30 +```
31 +[plugins]
32 + xenstat = no
33 +```
34 +
35 +## Debugging
36 +
37 +You can run the plugin by hand:
38 +
39 +```
40 +sudo /usr/libexec/netdata/plugins.d/xenstat.plugin 1 debug
41 +```
42 +
43 +You will get verbose output on what the plugin does.
44 +
45 +[![analytics](https://www.google-analytics.com/collect?v=1&aip=1&t=pageview&_s=1&ds=github&dr=https%3A%2F%2Fgithub.com%2Fnetdata%2Fnetdata&dl=https%3A%2F%2Fmy-netdata.io%2Fgithub%2Fcollectors%2Fnfacct.plugin%2FREADME&_u=MAC~&cid=5792dfd7-8dc4-476b-af31-da2fdb9f93d2&tid=UA-64295674-3)]()
collectors/xenstat.plugin/xenstat_plugin.c new
+1196
@@ -0,0 +1,1196 @@
1 +// SPDX-License-Identifier: GPL-3.0-or-later
2 +
3 +#include "../../libnetdata/libnetdata.h"
4 +
5 +#define PLUGIN_XENSTAT_NAME "xenstat.plugin"
6 +
7 +#define NETDATA_CHART_PRIO_XENSTAT_NODE_CPUS 30001
8 +#define NETDATA_CHART_PRIO_XENSTAT_NODE_CPU_FREQ 30002
9 +#define NETDATA_CHART_PRIO_XENSTAT_NODE_MEM 30003
10 +#define NETDATA_CHART_PRIO_XENSTAT_NODE_TMEM 30004
11 +#define NETDATA_CHART_PRIO_XENSTAT_NODE_DOMAINS 30005
12 +
13 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_STATES 30101
14 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_CPU 30102
15 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_VCPU 30103
16 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_MEM 30104
17 +
18 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_TMEM_PAGES 30104
19 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_TMEM_OPERATIONS 30105
20 +
21 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_VBD_OO_REQ 30200
22 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_VBD_REQUESTS 30300
23 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_VBD_SECTORS 30400
24 +
25 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_NET_BYTES 30500
26 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_NET_PACKETS 30600
27 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_NET_ERRORS 30700
28 +#define NETDATA_CHART_PRIO_XENSTAT_DOMAIN_NET_DROPS 30800
29 +
30 +#define TYPE_LENGTH_MAX 200
31 +
32 +#define CHART_IS_OBSOLETE 1
33 +#define CHART_IS_NOT_OBSOLETE 0
34 +
35 +// callback required by fatal()
36 +void netdata_cleanup_and_exit(int ret) {
37 + exit(ret);
38 +}
39 +
40 +void send_statistics( const char *action, const char *action_result, const char *action_data) {
41 + (void) action;
42 + (void) action_result;
43 + (void) action_data;
44 + return;
45 +}
46 +
47 +// callbacks required by popen()
48 +void signals_block(void) {};
49 +void signals_unblock(void) {};
50 +void signals_reset(void) {};
51 +
52 +// callback required by eval()
53 +int health_variable_lookup(const char *variable, uint32_t hash, struct rrdcalc *rc, calculated_number *result) {
54 + (void)variable;
55 + (void)hash;
56 + (void)rc;
57 + (void)result;
58 + return 0;
59 +};
60 +
61 +// required by get_system_cpus()
62 +char *netdata_configured_host_prefix = "";
63 +
64 +// Variables
65 +
66 +static int debug = 0;
67 +
68 +static int netdata_update_every = 1;
69 +
70 +#ifdef HAVE_LIBXENSTAT
71 +#include <xenstat.h>
72 +#include <libxl.h>
73 +
74 +struct vcpu_metrics {
75 + unsigned int id;
76 +
77 + unsigned int online;
78 + unsigned long long ns;
79 +
80 + int chart_generated;
81 + int updated;
82 +
83 + struct vcpu_metrics *next;
84 +};
85 +
86 +struct tmem_metrics {
87 + unsigned long long curr_eph_pages;
88 + unsigned long long succ_eph_gets;
89 + unsigned long long succ_pers_puts;
90 + unsigned long long succ_pers_gets;
91 +
92 + int pages_chart_generated;
93 + int operation_chart_generated;
94 +};
95 +
96 +struct vbd_metrics {
97 + unsigned int id;
98 +
99 + unsigned int error;
100 + unsigned long long oo_reqs;
101 + unsigned long long rd_reqs;
102 + unsigned long long wr_reqs;
103 + unsigned long long rd_sects;
104 + unsigned long long wr_sects;
105 +
106 + int oo_req_chart_generated;
107 + int requests_chart_generated;
108 + int sectors_chart_generated;
109 + int updated;
110 +
111 + struct vbd_metrics *next;
112 +};
113 +
114 +struct network_metrics {
115 + unsigned int id;
116 +
117 + unsigned long long rbytes;
118 + unsigned long long rpackets;
119 + unsigned long long rerrs;
120 + unsigned long long rdrops;
121 +
122 + unsigned long long tbytes;
123 + unsigned long long tpackets;
124 + unsigned long long terrs;
125 + unsigned long long tdrops;
126 +
127 + int bytes_chart_generated;
128 + int packets_chart_generated;
129 + int errors_chart_generated;
130 + int drops_chart_generated;
131 + int updated;
132 +
133 + struct network_metrics *next;
134 +};
135 +
136 +struct domain_metrics {
137 + char *uuid;
138 + uint32_t hash;
139 +
140 + unsigned int id;
141 + char *name;
142 +
143 + // states
144 + unsigned int running;
145 + unsigned int blocked;
146 + unsigned int paused;
147 + unsigned int shutdown;
148 + unsigned int crashed;
149 + unsigned int dying;
150 +
151 + unsigned long long cpu_ns;
152 + unsigned long long cur_mem;
153 + unsigned long long max_mem;
154 +
155 + struct tmem_metrics tmem;
156 + struct vcpu_metrics *vcpu_root;
157 + struct vbd_metrics *vbd_root;
158 + struct network_metrics *network_root;
159 +
160 + int states_chart_generated;
161 + int cpu_chart_generated;
162 + int vcpu_chart_generated;
163 + int num_vcpus_changed;
164 + int mem_chart_generated;
165 + int updated;
166 +
167 + struct domain_metrics *next;
168 +};
169 +
170 +struct node_metrics{
171 + unsigned long long tot_mem;
172 + unsigned long long free_mem;
173 + long freeable_mb;
174 + int num_domains;
175 + unsigned int num_cpus;
176 + unsigned long long node_cpu_hz;
177 +
178 + struct domain_metrics *domain_root;
179 +};
180 +
181 +static struct node_metrics node_metrics = {
182 + .domain_root = NULL
183 +};
184 +
185 +static inline struct domain_metrics *domain_metrics_get(const char *uuid, uint32_t hash) {
186 + struct domain_metrics *d = NULL, *last = NULL;
187 + for(d = node_metrics.domain_root; d ; last = d, d = d->next) {
188 + if(unlikely(d->hash == hash && !strcmp(d->uuid, uuid)))
189 + return d;
190 + }
191 +
192 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: allocating memory for domain with uuid %s\n", uuid);
193 +
194 + d = callocz(1, sizeof(struct domain_metrics));
195 + d->uuid = strdupz(uuid);
196 + d->hash = hash;
197 +
198 + if(unlikely(!last)) {
199 + d->next = node_metrics.domain_root;
200 + node_metrics.domain_root = d;
201 + }
202 + else {
203 + d->next = last->next;
204 + last->next = d;
205 + }
206 +
207 + return d;
208 +}
209 +
210 +static struct domain_metrics *domain_metrics_free(struct domain_metrics *d) {
211 + struct domain_metrics *cur = NULL, *last = NULL;
212 + struct vcpu_metrics *vcpu, *vcpu_f;
213 + struct vbd_metrics *vbd, *vbd_f;
214 + struct network_metrics *network, *network_f;
215 +
216 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: freeing memory for domain '%s' id %d, uuid %s\n", d->name, d->id, d->uuid);
217 +
218 + for(cur = node_metrics.domain_root; cur ; last = cur, cur = cur->next) {
219 + if(unlikely(cur->hash == d->hash && !strcmp(cur->uuid, d->uuid))) break;
220 + }
221 +
222 + if(unlikely(!cur)) {
223 + error("XENSTAT: failed to free domain metrics.");
224 + return NULL;
225 + }
226 +
227 + if(likely(last))
228 + last->next = cur->next;
229 + else
230 + node_metrics.domain_root = NULL;
231 +
232 + freez(cur->uuid);
233 + freez(cur->name);
234 +
235 + vcpu = cur->vcpu_root;
236 + while(vcpu) {
237 + vcpu_f = vcpu;
238 + vcpu = vcpu->next;
239 + freez(vcpu_f);
240 + }
241 +
242 + vbd = cur->vbd_root;
243 + while(vbd) {
244 + vbd_f = vbd;
245 + vbd = vbd->next;
246 + freez(vbd_f);
247 + }
248 +
249 + network = cur->network_root;
250 + while(network) {
251 + network_f = network;
252 + network = network->next;
253 + freez(network_f);
254 + }
255 +
256 + freez(cur);
257 +
258 + return last ? last : NULL;
259 +}
260 +
261 +static int vcpu_metrics_collect(struct domain_metrics *d, xenstat_domain *domain) {
262 + static unsigned int last_num_vcpus = 0;
263 + unsigned int num_vcpus = 0;
264 + xenstat_vcpu *vcpu = NULL;
265 + struct vcpu_metrics *vcpu_m = NULL, *last_vcpu_m = NULL;
266 +
267 + num_vcpus = xenstat_domain_num_vcpus(domain);
268 + if(unlikely(num_vcpus != last_num_vcpus)) {
269 + d->num_vcpus_changed = 1;
270 + last_num_vcpus = num_vcpus;
271 + }
272 +
273 + for(vcpu_m = d->vcpu_root; vcpu_m ; vcpu_m = vcpu_m->next)
274 + vcpu_m->updated = 0;
275 +
276 + vcpu_m = d->vcpu_root;
277 +
278 + unsigned int i;
279 + for(i = 0; i < num_vcpus; i++) {
280 + if(unlikely(!vcpu_m)) {
281 + vcpu_m = callocz(1, sizeof(struct vcpu_metrics));
282 +
283 + if(unlikely(i == 0)) d->vcpu_root = vcpu_m;
284 + else last_vcpu_m->next = vcpu_m;
285 + }
286 +
287 + vcpu_m->id = i;
288 +
289 + vcpu = xenstat_domain_vcpu(domain, i);
290 +
291 + if(unlikely(!vcpu)) {
292 + error("XENSTAT: cannot get VCPU statistics.");
293 + return 1;
294 + }
295 +
296 + vcpu_m->online = xenstat_vcpu_online(vcpu);
297 + vcpu_m->ns = xenstat_vcpu_ns(vcpu);
298 +
299 + vcpu_m->updated = 1;
300 +
301 + last_vcpu_m = vcpu_m;
302 + vcpu_m = vcpu_m->next;
303 + }
304 +
305 + return 0;
306 +}
307 +
308 +static int vbd_metrics_collect(struct domain_metrics *d, xenstat_domain *domain) {
309 + unsigned int num_vbds = xenstat_domain_num_vbds(domain);
310 + xenstat_vbd *vbd = NULL;
311 + struct vbd_metrics *vbd_m = NULL, *last_vbd_m = NULL;
312 +
313 + for(vbd_m = d->vbd_root; vbd_m ; vbd_m = vbd_m->next)
314 + vbd_m->updated = 0;
315 +
316 + vbd_m = d->vbd_root;
317 +
318 + unsigned int i;
319 + for(i = 0; i < num_vbds; i++) {
320 + if(unlikely(!vbd_m)) {
321 + vbd_m = callocz(1, sizeof(struct vbd_metrics));
322 +
323 + if(unlikely(i == 0)) d->vbd_root = vbd_m;
324 + else last_vbd_m->next = vbd_m;
325 + }
326 +
327 + vbd_m->id = i;
328 +
329 + vbd = xenstat_domain_vbd(domain, i);
330 +
331 + if(unlikely(!vbd)) {
332 + error("XENSTAT: cannot get VBD statistics.");
333 + return 1;
334 + }
335 +
336 + vbd_m->error = xenstat_vbd_error(vbd);
337 + vbd_m->oo_reqs = xenstat_vbd_oo_reqs(vbd);
338 + vbd_m->rd_reqs = xenstat_vbd_rd_reqs(vbd);
339 + vbd_m->wr_reqs = xenstat_vbd_wr_reqs(vbd);
340 + vbd_m->rd_sects = xenstat_vbd_rd_sects(vbd);
341 + vbd_m->wr_sects = xenstat_vbd_wr_sects(vbd);
342 +
343 + vbd_m->updated = 1;
344 +
345 + last_vbd_m = vbd_m;
346 + vbd_m = vbd_m->next;
347 + }
348 +
349 + return 0;
350 +}
351 +
352 +static int network_metrics_collect(struct domain_metrics *d, xenstat_domain *domain) {
353 + unsigned int num_networks = xenstat_domain_num_networks(domain);
354 + xenstat_network *network = NULL;
355 + struct network_metrics *network_m = NULL, *last_network_m = NULL;
356 +
357 + for(network_m = d->network_root; network_m ; network_m = network_m->next)
358 + network_m->updated = 0;
359 +
360 + network_m = d->network_root;
361 +
362 + unsigned int i;
363 + for(i = 0; i < num_networks; i++) {
364 + if(unlikely(!network_m)) {
365 + network_m = callocz(1, sizeof(struct network_metrics));
366 +
367 + if(unlikely(i == 0)) d->network_root = network_m;
368 + else last_network_m->next = network_m;
369 + }
370 +
371 + network_m->id = i;
372 +
373 + network = xenstat_domain_network(domain, i);
374 +
375 + if(unlikely(!network)) {
376 + error("XENSTAT: cannot get network statistics.");
377 + return 1;
378 + }
379 +
380 + network_m->rbytes = xenstat_network_rbytes(network);
381 + network_m->rpackets = xenstat_network_rpackets(network);
382 + network_m->rerrs = xenstat_network_rerrs(network);
383 + network_m->rdrops = xenstat_network_rdrop(network);
384 +
385 + network_m->tbytes = xenstat_network_tbytes(network);
386 + network_m->tpackets = xenstat_network_tpackets(network);
387 + network_m->terrs = xenstat_network_terrs(network);
388 + network_m->tdrops = xenstat_network_tdrop(network);
389 +
390 + network_m->updated = 1;
391 +
392 + last_network_m = network_m;
393 + network_m = network_m->next;
394 + }
395 +
396 + return 0;
397 +}
398 +
399 +static int xenstat_collect(xenstat_handle *xhandle, libxl_ctx *ctx, libxl_dominfo *info) {
400 +
401 + // mark all old metrics as not-updated
402 + struct domain_metrics *d;
403 + for(d = node_metrics.domain_root; d ; d = d->next)
404 + d->updated = 0;
405 +
406 + xenstat_node *node = xenstat_get_node(xhandle, XENSTAT_ALL);
407 + if (unlikely(!node)) {
408 + error("XENSTAT: failed to retrieve statistics from libxenstat.");
409 + return 1;
410 + }
411 +
412 + node_metrics.tot_mem = xenstat_node_tot_mem(node);
413 + node_metrics.free_mem = xenstat_node_free_mem(node);
414 + node_metrics.freeable_mb = xenstat_node_freeable_mb(node);
415 + node_metrics.num_domains = xenstat_node_num_domains(node);
416 + node_metrics.num_cpus = xenstat_node_num_cpus(node);
417 + node_metrics.node_cpu_hz = xenstat_node_cpu_hz(node);
418 +
419 + int i;
420 + for(i = 0; i < node_metrics.num_domains; i++) {
421 + xenstat_domain *domain = NULL;
422 + char uuid[LIBXL_UUID_FMTLEN + 1];
423 +
424 + domain = xenstat_node_domain_by_index(node, i);
425 +
426 + // get domain UUID
427 + unsigned int id = xenstat_domain_id(domain);
428 + if(unlikely(libxl_domain_info(ctx, info, id))) {
429 + error("XENSTAT: cannot get domain info.");
430 + }
431 + else {
432 + snprintfz(uuid, LIBXL_UUID_FMTLEN, LIBXL_UUID_FMT "\n", LIBXL_UUID_BYTES(info->uuid));
433 + }
434 +
435 + uint32_t hash = simple_hash(uuid);
436 + d = domain_metrics_get(uuid, hash);
437 +
438 + d->id = id;
439 + if(unlikely(!d->name)) {
440 + d->name = strdupz(xenstat_domain_name(domain));
441 + netdata_fix_chart_id(d->name);
442 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: domain id %d, uuid %s has name '%s'\n", d->id, d->uuid, d->name);
443 + }
444 +
445 + d->running = xenstat_domain_running(domain);
446 + d->blocked = xenstat_domain_blocked(domain);
447 + d->paused = xenstat_domain_paused(domain);
448 + d->shutdown = xenstat_domain_shutdown(domain);
449 + d->crashed = xenstat_domain_crashed(domain);
450 + d->dying = xenstat_domain_dying(domain);
451 +
452 + d->cpu_ns = xenstat_domain_cpu_ns(domain);
453 + d->cur_mem = xenstat_domain_cur_mem(domain);
454 + d->max_mem = xenstat_domain_max_mem(domain);
455 +
456 + xenstat_tmem *tmem = xenstat_domain_tmem(domain);
457 + d->tmem.curr_eph_pages = xenstat_tmem_curr_eph_pages(tmem);
458 + d->tmem.succ_eph_gets = xenstat_tmem_succ_eph_gets(tmem);
459 + d->tmem.succ_pers_puts = xenstat_tmem_succ_pers_puts(tmem);
460 + d->tmem.succ_pers_gets = xenstat_tmem_succ_pers_gets(tmem);
461 +
462 + if(unlikely(vcpu_metrics_collect(d, domain) || vbd_metrics_collect(d, domain) || network_metrics_collect(d, domain))) {
463 + xenstat_free_node(node);
464 + return 1;
465 + }
466 +
467 + d->updated = 1;
468 + }
469 +
470 + xenstat_free_node(node);
471 +
472 + return 0;
473 +}
474 +
475 +static void xenstat_send_node_metrics() {
476 + static int mem_chart_generated = 0, tmem_chart_generated = 0, domains_chart_generated = 0, cpus_chart_generated = 0, cpu_freq_chart_generated = 0;
477 +
478 + // ----------------------------------------------------------------
479 +
480 + if(unlikely(!mem_chart_generated)) {
481 + printf("CHART xenstat.mem '' 'Memory Usage' 'MiB' 'memory' '' stacked %d %d '' %s\n"
482 + , NETDATA_CHART_PRIO_XENSTAT_NODE_MEM
483 + , netdata_update_every
484 + , PLUGIN_XENSTAT_NAME
485 + );
486 + printf("DIMENSION %s '' absolute 1 %d\n", "free", netdata_update_every * 1024 * 1024);
487 + printf("DIMENSION %s '' absolute 1 %d\n", "used", netdata_update_every * 1024 * 1024);
488 + mem_chart_generated = 1;
489 + }
490 +
491 + printf(
492 + "BEGIN xenstat.mem\n"
493 + "SET free = %lld\n"
494 + "SET used = %lld\n"
495 + "END\n"
496 + , (collected_number) node_metrics.free_mem
497 + , (collected_number) (node_metrics.tot_mem - node_metrics.free_mem)
498 + );
499 +
500 + // ----------------------------------------------------------------
501 +
502 + if(unlikely(!tmem_chart_generated)) {
503 + printf("CHART xenstat.tmem '' 'Freeable Transcedent Memory' 'MiB' 'memory' '' line %d %d '' %s\n"
504 + , NETDATA_CHART_PRIO_XENSTAT_NODE_TMEM
505 + , netdata_update_every
506 + , PLUGIN_XENSTAT_NAME
507 + );
508 + printf("DIMENSION %s '' absolute 1 %d\n", "freeable", netdata_update_every * 1024 * 1024);
509 + tmem_chart_generated = 1;
510 + }
511 +
512 + printf(
513 + "BEGIN xenstat.tmem\n"
514 + "SET freeable = %lld\n"
515 + "END\n"
516 + , (collected_number) node_metrics.freeable_mb
517 + );
518 +
519 + // ----------------------------------------------------------------
520 +
521 + if(unlikely(!domains_chart_generated)) {
522 + printf("CHART xenstat.domains '' 'Number of Domains' 'domains' 'domains' '' line %d %d '' %s\n"
523 + , NETDATA_CHART_PRIO_XENSTAT_NODE_DOMAINS
524 + , netdata_update_every
525 + , PLUGIN_XENSTAT_NAME
526 + );
527 + printf("DIMENSION %s '' absolute 1 %d\n", "domains", netdata_update_every);
528 + domains_chart_generated = 1;
529 + }
530 +
531 + printf(
532 + "BEGIN xenstat.domains\n"
533 + "SET domains = %lld\n"
534 + "END\n"
535 + , (collected_number) node_metrics.num_domains
536 + );
537 +
538 + // ----------------------------------------------------------------
539 +
540 + if(unlikely(!cpus_chart_generated)) {
541 + printf("CHART xenstat.cpus '' 'Number of CPUs' 'cpus' 'cpu' '' line %d %d '' %s\n"
542 + , NETDATA_CHART_PRIO_XENSTAT_NODE_CPUS
543 + , netdata_update_every
544 + , PLUGIN_XENSTAT_NAME
545 + );
546 + printf("DIMENSION %s '' absolute 1 %d\n", "cpus", netdata_update_every);
547 + cpus_chart_generated = 1;
548 + }
549 +
550 + printf(
551 + "BEGIN xenstat.cpus\n"
552 + "SET cpus = %lld\n"
553 + "END\n"
554 + , (collected_number) node_metrics.num_cpus
555 + );
556 +
557 + // ----------------------------------------------------------------
558 +
559 + if(unlikely(!cpu_freq_chart_generated)) {
560 + printf("CHART xenstat.cpu_freq '' 'CPU Frequency' 'MHz' 'cpu' '' line %d %d '' %s\n"
561 + , NETDATA_CHART_PRIO_XENSTAT_NODE_CPU_FREQ
562 + , netdata_update_every
563 + , PLUGIN_XENSTAT_NAME
564 + );
565 + printf("DIMENSION %s '' absolute 1 %d\n", "frequency", netdata_update_every * 1024 * 1024);
566 + cpu_freq_chart_generated = 1;
567 + }
568 +
569 + printf(
570 + "BEGIN xenstat.cpu_freq\n"
571 + "SET frequency = %lld\n"
572 + "END\n"
573 + , (collected_number) node_metrics.node_cpu_hz
574 + );
575 +}
576 +
577 +static void print_domain_states_chart_definition(char *type, int obsolete_flag) {
578 + printf("CHART %s.states '' 'Domain States' 'boolean' 'states' 'xendomain.states' line %d %d %s %s\n"
579 + , type
580 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_STATES
581 + , netdata_update_every
582 + , obsolete_flag ? "obsolete": "''"
583 + , PLUGIN_XENSTAT_NAME
584 + );
585 + printf("DIMENSION running '' absolute 1 %d\n", netdata_update_every);
586 + printf("DIMENSION blocked '' absolute 1 %d\n", netdata_update_every);
587 + printf("DIMENSION paused '' absolute 1 %d\n", netdata_update_every);
588 + printf("DIMENSION shutdown '' absolute 1 %d\n", netdata_update_every);
589 + printf("DIMENSION crashed '' absolute 1 %d\n", netdata_update_every);
590 + printf("DIMENSION dying '' absolute 1 %d\n", netdata_update_every);
591 +}
592 +
593 +static void print_domain_cpu_chart_definition(char *type, int obsolete_flag) {
594 + printf("CHART %s.cpu '' 'CPU Usage (100%% = 1 core)' 'percentage' 'cpu' 'xendomain.cpu' line %d %d %s %s\n"
595 + , type
596 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_CPU
597 + , netdata_update_every
598 + , obsolete_flag ? "obsolete": "''"
599 + , PLUGIN_XENSTAT_NAME
600 + );
601 + printf("DIMENSION used '' incremental 100 %d\n", netdata_update_every * 1000000000);
602 +}
603 +
604 +static void print_domain_mem_chart_definition(char *type, int obsolete_flag) {
605 + printf("CHART %s.mem '' 'Memory Reservation' 'MiB' 'memory' 'xendomain.mem' line %d %d %s %s\n"
606 + , type
607 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_MEM
608 + , netdata_update_every
609 + , obsolete_flag ? "obsolete": "''"
610 + , PLUGIN_XENSTAT_NAME
611 + );
612 + printf("DIMENSION maximum '' absolute 1 %d\n", netdata_update_every * 1024 * 1024);
613 + printf("DIMENSION current '' absolute 1 %d\n", netdata_update_every * 1024 * 1024);
614 +}
615 +
616 +static void print_domain_tmem_pages_chart_definition(char *type, int obsolete_flag) {
617 + printf("CHART %s.tmem_pages '' 'Current Number of Transcedent Memory Ephemeral Pages' 'pages' 'memory' 'xendomain.tmem_pages' line %d %d %s %s\n"
618 + , type
619 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_TMEM_PAGES
620 + , netdata_update_every
621 + , obsolete_flag ? "obsolete": "''"
622 + , PLUGIN_XENSTAT_NAME
623 + );
624 + printf("DIMENSION pages '' absolute 1 %d\n", netdata_update_every);
625 +}
626 +
627 +static void print_domain_tmem_operations_chart_definition(char *type, int obsolete_flag) {
628 + printf("CHART %s.tmem_operations '' 'Successful Transcedent Memory Puts and Gets' 'events/s' 'memory' 'xendomain.tmem_operations' line %d %d %s %s\n"
629 + , type
630 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_TMEM_OPERATIONS
631 + , netdata_update_every
632 + , obsolete_flag ? "obsolete": "''"
633 + , PLUGIN_XENSTAT_NAME
634 + );
635 + printf("DIMENSION ephemeral_gets 'ephemeral gets' incremental 1 %d\n", netdata_update_every);
636 + printf("DIMENSION persistent_puts 'persistent puts' incremental 1 %d\n", netdata_update_every);
637 + printf("DIMENSION persistent_gets 'persistent gets' incremental 1 %d\n", netdata_update_every);
638 +}
639 +
640 +static void print_domain_vcpu_chart_definition(char *type, struct domain_metrics *d, int obsolete_flag) {
641 + struct vcpu_metrics *vcpu_m;
642 +
643 + printf("CHART %s.vcpu '' 'CPU Usage per VCPU' 'percentage' 'cpu' 'xendomain.vcpu' line %d %d %s %s\n"
644 + , type
645 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_VCPU
646 + , netdata_update_every
647 + , obsolete_flag ? "obsolete": "''"
648 + , PLUGIN_XENSTAT_NAME
649 + );
650 +
651 + for(vcpu_m = d->vcpu_root; vcpu_m; vcpu_m = vcpu_m->next) {
652 + if(likely(vcpu_m->updated && vcpu_m->online)) {
653 + printf("DIMENSION vcpu%u '' incremental 100 %d\n", vcpu_m->id, netdata_update_every * 1000000000);
654 + }
655 + }
656 +}
657 +
658 +static void print_domain_vbd_oo_chart_definition(char *type, unsigned int vbd, int obsolete_flag) {
659 + printf("CHART %s.oo_req_vbd%u '' 'VBD%u \"Out Of\" Requests' 'requests/s' 'vbd' 'xendomain.oo_req_vbd' line %d %d %s %s\n"
660 + , type
661 + , vbd
662 + , vbd
663 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_VBD_OO_REQ + vbd
664 + , netdata_update_every
665 + , obsolete_flag ? "obsolete": "''"
666 + , PLUGIN_XENSTAT_NAME
667 + );
668 + printf("DIMENSION requests '' incremental 1 %d\n", netdata_update_every);
669 +}
670 +
671 +static void print_domain_vbd_requests_chart_definition(char *type, unsigned int vbd, int obsolete_flag) {
672 + printf("CHART %s.requests_vbd%u '' 'VBD%u Requests' 'requests/s' 'vbd' 'xendomain.requests_vbd' line %d %d %s %s\n"
673 + , type
674 + , vbd
675 + , vbd
676 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_VBD_REQUESTS + vbd
677 + , netdata_update_every
678 + , obsolete_flag ? "obsolete": "''"
679 + , PLUGIN_XENSTAT_NAME
680 + );
681 + printf("DIMENSION read '' incremental 1 %d\n", netdata_update_every);
682 + printf("DIMENSION write '' incremental -1 %d\n", netdata_update_every);
683 +}
684 +
685 +static void print_domain_vbd_sectors_chart_definition(char *type, unsigned int vbd, int obsolete_flag) {
686 + printf("CHART %s.sectors_vbd%u '' 'VBD%u Read/Written Sectors' 'sectors/s' 'vbd' 'xendomain.sectors_vbd' line %d %d %s %s\n"
687 + , type
688 + , vbd
689 + , vbd
690 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_VBD_SECTORS + vbd
691 + , netdata_update_every
692 + , obsolete_flag ? "obsolete": "''"
693 + , PLUGIN_XENSTAT_NAME
694 + );
695 + printf("DIMENSION read '' incremental 1 %d\n", netdata_update_every);
696 + printf("DIMENSION write '' incremental -1 %d\n", netdata_update_every);
697 +}
698 +
699 +static void print_domain_network_bytes_chart_definition(char *type, unsigned int network, int obsolete_flag) {
700 + printf("CHART %s.bytes_network%u '' 'Network%u Received/Sent Bytes' 'kilobits/s' 'network' 'xendomain.bytes_network' line %d %d %s %s\n"
701 + , type
702 + , network
703 + , network
704 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_NET_BYTES + network
705 + , netdata_update_every
706 + , obsolete_flag ? "obsolete": "''"
707 + , PLUGIN_XENSTAT_NAME
708 + );
709 + printf("DIMENSION received '' incremental 8 %d\n", netdata_update_every * 1000);
710 + printf("DIMENSION sent '' incremental -8 %d\n", netdata_update_every * 1000);
711 +}
712 +
713 +static void print_domain_network_packets_chart_definition(char *type, unsigned int network, int obsolete_flag) {
714 + printf("CHART %s.packets_network%u '' 'Network%u Recieved/Sent Packets' 'packets/s' 'network' 'xendomain.packets_network' line %d %d %s %s\n"
715 + , type
716 + , network
717 + , network
718 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_NET_PACKETS + network
719 + , netdata_update_every
720 + , obsolete_flag ? "obsolete": "''"
721 + , PLUGIN_XENSTAT_NAME
722 + );
723 + printf("DIMENSION received '' incremental 1 %d\n", netdata_update_every);
724 + printf("DIMENSION sent '' incremental -1 %d\n", netdata_update_every);
725 +}
726 +
727 +static void print_domain_network_errors_chart_definition(char *type, unsigned int network, int obsolete_flag) {
728 + printf("CHART %s.errors_network%u '' 'Network%u Receive/Transmit Errors' 'errors/s' 'network' 'xendomain.errors_network' line %d %d %s %s\n"
729 + , type
730 + , network
731 + , network
732 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_NET_PACKETS + network
733 + , netdata_update_every
734 + , obsolete_flag ? "obsolete": "''"
735 + , PLUGIN_XENSTAT_NAME
736 + );
737 + printf("DIMENSION received '' incremental 1 %d\n", netdata_update_every);
738 + printf("DIMENSION sent '' incremental -1 %d\n", netdata_update_every);
739 +}
740 +
741 +static void print_domain_network_drops_chart_definition(char *type, unsigned int network, int obsolete_flag) {
742 + printf("CHART %s.drops_network%u '' 'Network%u Recieve/Transmit Drops' 'drops/s' 'network' 'xendomain.drops_network' line %d %d %s %s\n"
743 + , type
744 + , network
745 + , network
746 + , NETDATA_CHART_PRIO_XENSTAT_DOMAIN_NET_PACKETS + network
747 + , netdata_update_every
748 + , obsolete_flag ? "obsolete": "''"
749 + , PLUGIN_XENSTAT_NAME
750 + );
751 + printf("DIMENSION received '' incremental 1 %d\n", netdata_update_every);
752 + printf("DIMENSION sent '' incremental -1 %d\n", netdata_update_every);
753 +}
754 +
755 +static void xenstat_send_domain_metrics() {
756 +
757 + if(unlikely(!node_metrics.domain_root)) return;
758 + struct domain_metrics *d;
759 +
760 + for(d = node_metrics.domain_root; d; d = d->next) {
761 + char type[TYPE_LENGTH_MAX + 1];
762 + snprintfz(type, TYPE_LENGTH_MAX, "xendomain_%s_%s", d->name, d->uuid);
763 +
764 + if(likely(d->updated)) {
765 +
766 + // ----------------------------------------------------------------
767 +
768 + if(unlikely(!d->states_chart_generated)) {
769 + print_domain_states_chart_definition(type, CHART_IS_NOT_OBSOLETE);
770 + d->states_chart_generated = 1;
771 + }
772 + printf(
773 + "BEGIN %s.states\n"
774 + "SET running = %lld\n"
775 + "SET blocked = %lld\n"
776 + "SET paused = %lld\n"
777 + "SET shutdown = %lld\n"
778 + "SET crashed = %lld\n"
779 + "SET dying = %lld\n"
780 + "END\n"
781 + , type
782 + , (collected_number)d->running
783 + , (collected_number)d->blocked
784 + , (collected_number)d->paused
785 + , (collected_number)d->shutdown
786 + , (collected_number)d->crashed
787 + , (collected_number)d->dying
788 + );
789 +
790 + // ----------------------------------------------------------------
791 +
792 + if(unlikely(!d->cpu_chart_generated)) {
793 + print_domain_cpu_chart_definition(type, CHART_IS_NOT_OBSOLETE);
794 + d->cpu_chart_generated = 1;
795 + }
796 + printf(
797 + "BEGIN %s.cpu\n"
798 + "SET used = %lld\n"
799 + "END\n"
800 + , type
801 + , (collected_number)d->cpu_ns
802 + );
803 +
804 + // ----------------------------------------------------------------
805 +
806 + struct vcpu_metrics *vcpu_m;
807 +
808 + if(unlikely(!d->vcpu_chart_generated || d->num_vcpus_changed)) {
809 + print_domain_vcpu_chart_definition(type, d, CHART_IS_NOT_OBSOLETE);
810 + d->num_vcpus_changed = 0;
811 + d->vcpu_chart_generated = 1;
812 + }
813 +
814 + printf("BEGIN %s.vcpu\n", type);
815 + for(vcpu_m = d->vcpu_root; vcpu_m; vcpu_m = vcpu_m->next) {
816 + if(likely(vcpu_m->updated && vcpu_m->online)) {
817 + printf(
818 + "SET vcpu%u = %lld\n"
819 + , vcpu_m->id
820 + , (collected_number)vcpu_m->ns
821 + );
822 + }
823 + }
824 + printf("END\n");
825 +
826 + // ----------------------------------------------------------------
827 +
828 + if(unlikely(!d->mem_chart_generated)) {
829 + print_domain_mem_chart_definition(type, CHART_IS_NOT_OBSOLETE);
830 + d->mem_chart_generated = 1;
831 + }
832 + printf(
833 + "BEGIN %s.mem\n"
834 + "SET maximum = %lld\n"
835 + "SET current = %lld\n"
836 + "END\n"
837 + , type
838 + , (collected_number)d->max_mem
839 + , (collected_number)d->cur_mem
840 + );
841 +
842 + // ----------------------------------------------------------------
843 +
844 + if(unlikely(!d->tmem.pages_chart_generated)) {
845 + print_domain_tmem_pages_chart_definition(type, CHART_IS_NOT_OBSOLETE);
846 + d->tmem.pages_chart_generated = 1;
847 + }
848 + printf(
849 + "BEGIN %s.tmem_pages\n"
850 + "SET pages = %lld\n"
851 + "END\n"
852 + , type
853 + , (collected_number)d->tmem.curr_eph_pages
854 + );
855 +
856 + // ----------------------------------------------------------------
857 +
858 + if(unlikely(!d->tmem.operation_chart_generated)) {
859 + print_domain_tmem_operations_chart_definition(type, CHART_IS_NOT_OBSOLETE);
860 + d->tmem.operation_chart_generated = 1;
861 + }
862 + printf(
863 + "BEGIN %s.tmem_operations\n"
864 + "SET ephemeral_gets = %lld\n"
865 + "SET persistent_puts = %lld\n"
866 + "SET persistent_gets = %lld\n"
867 + "END\n"
868 + , type
869 + , (collected_number)d->tmem.succ_eph_gets
870 + , (collected_number)d->tmem.succ_pers_puts
871 + , (collected_number)d->tmem.succ_eph_gets
872 + );
873 +
874 + // ----------------------------------------------------------------
875 +
876 + struct vbd_metrics *vbd_m;
877 + for(vbd_m = d->vbd_root; vbd_m; vbd_m = vbd_m->next) {
878 + if(likely(vbd_m->updated && !vbd_m->error)) {
879 + if(unlikely(!vbd_m->oo_req_chart_generated)) {
880 + print_domain_vbd_oo_chart_definition(type, vbd_m->id, CHART_IS_NOT_OBSOLETE);
881 + vbd_m->oo_req_chart_generated = 1;
882 + }
883 + printf(
884 + "BEGIN %s.oo_req_vbd%u\n"
885 + "SET requests = %lld\n"
886 + "END\n"
887 + , type
888 + , vbd_m->id
889 + , (collected_number)vbd_m->oo_reqs
890 + );
891 +
892 + // ----------------------------------------------------------------
893 +
894 + if(unlikely(!vbd_m->requests_chart_generated)) {
895 + print_domain_vbd_requests_chart_definition(type, vbd_m->id, CHART_IS_NOT_OBSOLETE);
896 + vbd_m->requests_chart_generated = 1;
897 + }
898 + printf(
899 + "BEGIN %s.requests_vbd%u\n"
900 + "SET read = %lld\n"
901 + "SET write = %lld\n"
902 + "END\n"
903 + , type
904 + , vbd_m->id
905 + , (collected_number)vbd_m->rd_reqs
906 + , (collected_number)vbd_m->wr_reqs
907 + );
908 +
909 + // ----------------------------------------------------------------
910 +
911 + if(unlikely(!vbd_m->sectors_chart_generated)) {
912 + print_domain_vbd_sectors_chart_definition(type, vbd_m->id, CHART_IS_NOT_OBSOLETE);
913 + vbd_m->sectors_chart_generated = 1;
914 + }
915 + printf(
916 + "BEGIN %s.sectors_vbd%u\n"
917 + "SET read = %lld\n"
918 + "SET write = %lld\n"
919 + "END\n"
920 + , type
921 + , vbd_m->id
922 + , (collected_number)vbd_m->rd_sects
923 + , (collected_number)vbd_m->wr_sects
924 + );
925 + }
926 + else {
927 + if(unlikely(vbd_m->oo_req_chart_generated
928 + || vbd_m->requests_chart_generated
929 + || vbd_m->sectors_chart_generated)) {
930 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: mark charts as obsolete for vbd %d, domain '%s', id %d, uuid %s\n", vbd_m->id, d->name, d->id, d->uuid);
931 + print_domain_vbd_oo_chart_definition(type, vbd_m->id, CHART_IS_OBSOLETE);
932 + print_domain_vbd_requests_chart_definition(type, vbd_m->id, CHART_IS_OBSOLETE);
933 + print_domain_vbd_sectors_chart_definition(type, vbd_m->id, CHART_IS_OBSOLETE);
934 + vbd_m->oo_req_chart_generated = 0;
935 + vbd_m->requests_chart_generated = 0;
936 + vbd_m->sectors_chart_generated = 0;
937 + }
938 + }
939 + }
940 +
941 + // ----------------------------------------------------------------
942 +
943 + struct network_metrics *network_m;
944 + for(network_m = d->network_root; network_m; network_m = network_m->next) {
945 + if(likely(network_m->updated)) {
946 + if(unlikely(!network_m->bytes_chart_generated)) {
947 + print_domain_network_bytes_chart_definition(type, network_m->id, CHART_IS_NOT_OBSOLETE);
948 + network_m->bytes_chart_generated = 1;
949 + }
950 + printf(
951 + "BEGIN %s.bytes_network%u\n"
952 + "SET recieved = %lld\n"
953 + "SET sent = %lld\n"
954 + "END\n"
955 + , type
956 + , network_m->id
957 + , (collected_number)network_m->rbytes
958 + , (collected_number)network_m->tbytes
959 + );
960 +
961 + // ----------------------------------------------------------------
962 +
963 + if(unlikely(!network_m->packets_chart_generated)) {
964 + print_domain_network_packets_chart_definition(type, network_m->id, CHART_IS_NOT_OBSOLETE);
965 + network_m->packets_chart_generated = 1;
966 + }
967 + printf(
968 + "BEGIN %s.packets_network%u\n"
969 + "SET recieved = %lld\n"
970 + "SET sent = %lld\n"
971 + "END\n"
972 + , type
973 + , network_m->id
974 + , (collected_number)network_m->rpackets
975 + , (collected_number)network_m->tpackets
976 + );
977 +
978 + // ----------------------------------------------------------------
979 +
980 + if(unlikely(!network_m->errors_chart_generated)) {
981 + print_domain_network_errors_chart_definition(type, network_m->id, CHART_IS_NOT_OBSOLETE);
982 + network_m->errors_chart_generated = 1;
983 + }
984 + printf(
985 + "BEGIN %s.errors_network%u\n"
986 + "SET recieved = %lld\n"
987 + "SET sent = %lld\n"
988 + "END\n"
989 + , type
990 + , network_m->id
991 + , (collected_number)network_m->rerrs
992 + , (collected_number)network_m->terrs
993 + );
994 +
995 + // ----------------------------------------------------------------
996 +
997 + if(unlikely(!network_m->drops_chart_generated)) {
998 + print_domain_network_drops_chart_definition(type, network_m->id, CHART_IS_NOT_OBSOLETE);
999 + network_m->drops_chart_generated = 1;
1000 + }
1001 + printf(
1002 + "BEGIN %s.drops_network%u\n"
1003 + "SET recieved = %lld\n"
1004 + "SET sent = %lld\n"
1005 + "END\n"
1006 + , type
1007 + , network_m->id
1008 + , (collected_number)network_m->rdrops
1009 + , (collected_number)network_m->tdrops
1010 + );
1011 + }
1012 + else {
1013 + if(unlikely(network_m->bytes_chart_generated
1014 + || network_m->packets_chart_generated
1015 + || network_m->errors_chart_generated
1016 + || network_m->drops_chart_generated))
1017 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: mark charts as obsolete for network %d, domain '%s', id %d, uuid %s\n", network_m->id, d->name, d->id, d->uuid);
1018 + print_domain_network_bytes_chart_definition(type, network_m->id, CHART_IS_OBSOLETE);
1019 + print_domain_network_packets_chart_definition(type, network_m->id, CHART_IS_OBSOLETE);
1020 + print_domain_network_errors_chart_definition(type, network_m->id, CHART_IS_OBSOLETE);
1021 + print_domain_network_drops_chart_definition(type, network_m->id, CHART_IS_OBSOLETE);
1022 + network_m->bytes_chart_generated = 0;
1023 + network_m->packets_chart_generated = 0;
1024 + network_m->errors_chart_generated = 0;
1025 + network_m->drops_chart_generated = 0;
1026 + }
1027 + }
1028 + }
1029 + else{
1030 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: mark charts as obsolete for domain '%s', id %d, uuid %s\n", d->name, d->id, d->uuid);
1031 + print_domain_states_chart_definition(type, CHART_IS_OBSOLETE);
1032 + print_domain_cpu_chart_definition(type, CHART_IS_OBSOLETE);
1033 + print_domain_vcpu_chart_definition(type, d, CHART_IS_OBSOLETE);
1034 + print_domain_mem_chart_definition(type, CHART_IS_OBSOLETE);
1035 + print_domain_tmem_pages_chart_definition(type, CHART_IS_OBSOLETE);
1036 + print_domain_tmem_operations_chart_definition(type, CHART_IS_OBSOLETE);
1037 +
1038 + d = domain_metrics_free(d);
1039 + }
1040 + }
1041 +}
1042 +
1043 +int main(int argc, char **argv) {
1044 +
1045 + // ------------------------------------------------------------------------
1046 + // initialization of netdata plugin
1047 +
1048 + program_name = "xenstat.plugin";
1049 +
1050 + // disable syslog
1051 + error_log_syslog = 0;
1052 +
1053 + // set errors flood protection to 100 logs per hour
1054 + error_log_errors_per_period = 100;
1055 + error_log_throttle_period = 3600;
1056 +
1057 + // ------------------------------------------------------------------------
1058 + // parse command line parameters
1059 +
1060 + int i, freq = 0;
1061 + for(i = 1; i < argc ; i++) {
1062 + if(isdigit(*argv[i]) && !freq) {
1063 + int n = str2i(argv[i]);
1064 + if(n > 0 && n < 86400) {
1065 + freq = n;
1066 + continue;
1067 + }
1068 + }
1069 + else if(strcmp("version", argv[i]) == 0 || strcmp("-version", argv[i]) == 0 || strcmp("--version", argv[i]) == 0 || strcmp("-v", argv[i]) == 0 || strcmp("-V", argv[i]) == 0) {
1070 + printf("xenstat.plugin %s\n", VERSION);
1071 + exit(0);
1072 + }
1073 + else if(strcmp("debug", argv[i]) == 0) {
1074 + debug = 1;
1075 + continue;
1076 + }
1077 + else if(strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
1078 + fprintf(stderr,
1079 + "\n"
1080 + " netdata xenstat.plugin %s\n"
1081 + " Copyright (C) 2019 Netdata Inc.\n"
1082 + " Released under GNU General Public License v3 or later.\n"
1083 + " All rights reserved.\n"
1084 + "\n"
1085 + " This program is a data collector plugin for netdata.\n"
1086 + "\n"
1087 + " Available command line options:\n"
1088 + "\n"
1089 + " COLLECTION_FREQUENCY data collection frequency in seconds\n"
1090 + " minimum: %d\n"
1091 + "\n"
1092 + " debug enable verbose output\n"
1093 + " default: disabled\n"
1094 + "\n"
1095 + " -v\n"
1096 + " -V\n"
1097 + " --version print version and exit\n"
1098 + "\n"
1099 + " -h\n"
1100 + " --help print this message and exit\n"
1101 + "\n"
1102 + " For more information:\n"
1103 + " https://github.com/netdata/netdata/tree/master/collectors/xenstat.plugin\n"
1104 + "\n"
1105 + , VERSION
1106 + , netdata_update_every
1107 + );
1108 + exit(1);
1109 + }
1110 +
1111 + error("xenstat.plugin: ignoring parameter '%s'", argv[i]);
1112 + }
1113 +
1114 + errno = 0;
1115 +
1116 + if(freq >= netdata_update_every)
1117 + netdata_update_every = freq;
1118 + else if(freq)
1119 + error("update frequency %d seconds is too small for XENSTAT. Using %d.", freq, netdata_update_every);
1120 +
1121 + // ------------------------------------------------------------------------
1122 + // initialize xen API handles
1123 + xenstat_handle *xhandle = NULL;
1124 + libxl_ctx *ctx = NULL;
1125 + libxl_dominfo info;
1126 +
1127 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: calling xenstat_init()\n");
1128 + xhandle = xenstat_init();
1129 + if (xhandle == NULL)
1130 + error("XENSTAT: failed to initialize xenstat library.");
1131 +
1132 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: calling libxl_ctx_alloc()\n");
1133 + if (libxl_ctx_alloc(&ctx, LIBXL_VERSION, 0, NULL)) {
1134 + error("XENSTAT: failed to initialize xl context.");
1135 + }
1136 + libxl_dominfo_init(&info);
1137 +
1138 + // ------------------------------------------------------------------------
1139 + // the main loop
1140 +
1141 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: starting data collection\n");
1142 +
1143 + time_t started_t = now_monotonic_sec();
1144 +
1145 + size_t iteration;
1146 + usec_t step = netdata_update_every * USEC_PER_SEC;
1147 +
1148 + heartbeat_t hb;
1149 + heartbeat_init(&hb);
1150 + for(iteration = 0; 1; iteration++) {
1151 + usec_t dt = heartbeat_next(&hb, step);
1152 +
1153 + if(unlikely(netdata_exit)) break;
1154 +
1155 + if(unlikely(debug && iteration))
1156 + fprintf(stderr, "xenstat.plugin: iteration %zu, dt %llu usec\n"
1157 + , iteration
1158 + , dt
1159 + );
1160 +
1161 + if(likely(xhandle)) {
1162 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: calling xenstat_collect()\n");
1163 + int ret = xenstat_collect(xhandle, ctx, &info);
1164 +
1165 + if(likely(!ret)) {
1166 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: calling xenstat_send_node_metrics()\n");
1167 + xenstat_send_node_metrics();
1168 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: calling xenstat_send_domain_metrics()\n");
1169 + xenstat_send_domain_metrics();
1170 + }
1171 + else {
1172 + if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: can't collect data\n");
1173 + }
1174 + }
1175 +
1176 + fflush(stdout);
1177 +
1178 + // restart check (14400 seconds)
1179 + if(unlikely(now_monotonic_sec() - started_t > 14400)) break;
1180 + }
1181 +
1182 + libxl_ctx_free(ctx);
1183 + xenstat_uninit(xhandle);
1184 + info("XENSTAT process exiting");
1185 +}
1186 +
1187 +#else // !HAVE_LIBXENSTAT
1188 +
1189 +int main(int argc, char **argv) {
1190 + (void)argc;
1191 + (void)argv;
1192 +
1193 + fatal("xenstat.plugin is not compiled.");
1194 +}
1195 +
1196 +#endif // !HAVE_LIBXENSTAT
configure.ac
+91 -15
@@ -57,12 +57,18 @@ AC_ARG_ENABLE(
57 ,
58 [enable_plugin_freeipmi="detect"]
59 )
60 - AC_ARG_ENABLE(
60 +AC_ARG_ENABLE(
61 [plugin-cups],
62 [AS_HELP_STRING([--enable-plugin-cups], [enable cups plugin @<:@default autodetect@:>@])],
63 ,
64 [enable_plugin_cups="detect"]
65 - )
65 +)
66 +AC_ARG_ENABLE(
67 + [plugin-xenstat],
68 + [AS_HELP_STRING([--enable-plugin-xenstat], [enable xenstat plugin @<:@default autodetect@:>@])],
69 + ,
70 + [enable_plugin_xenstat="detect"]
71 +)
72
73 AC_ARG_ENABLE(
74 [pedantic],
@@ -407,10 +413,10 @@ AM_CONDITIONAL([ENABLE_PLUGIN_FREEIPMI], [test "${enable_plugin_freeipmi}" = "ye
413
414
415 # -----------------------------------------------------------------------------
410 -# cups.plugin - libmnl, libnetfilter_acct
416 +# cups.plugin - libcups
417
418 # Only check most recently added method of cups
413 - AC_CHECK_LIB([cups], [httpConnect2],
419 +AC_CHECK_LIB([cups], [httpConnect2],
420 [AC_CHECK_HEADER(
421 [cups/cups.h],
422 [have_cups=yes],
@@ -463,11 +469,11 @@ PKG_CHECK_MODULES(
469 [NFACCT],
470 [libnetfilter_acct],
471 [AC_CHECK_LIB(
466 - [netfilter_acct],
467 - [nfacct_alloc],
468 - [have_libnetfilter_acct=yes],
469 - [have_libnetfilter_acct=no]
470 - )],
472 + [netfilter_acct],
473 + [nfacct_alloc],
474 + [have_libnetfilter_acct=yes],
475 + [have_libnetfilter_acct=no]
476 + )],
477 [have_libnetfilter_acct=no]
478 )
479
@@ -475,11 +481,11 @@ PKG_CHECK_MODULES(
481 [LIBMNL],
482 [libmnl],
483 [AC_CHECK_LIB(
478 - [mnl],
479 - [mnl_socket_open],
480 - [have_libmnl=yes],
481 - [have_libmnl=no]
482 - )],
484 + [mnl],
485 + [mnl_socket_open],
486 + [have_libmnl=yes],
487 + [have_libmnl=no]
488 + )],
489 [have_libmnl=no]
490 )
491
@@ -503,6 +509,73 @@ AC_MSG_RESULT([${enable_plugin_nfacct}])
509 AM_CONDITIONAL([ENABLE_PLUGIN_NFACCT], [test "${enable_plugin_nfacct}" = "yes"])
510
511
512 +# -----------------------------------------------------------------------------
513 +# xenstat.plugin - libxenstat
514 +
515 +PKG_CHECK_MODULES(
516 + [YAJL],
517 + [yajl],
518 + [AC_CHECK_LIB(
519 + [yajl],
520 + [yajl_tree_get],
521 + [have_libyajl=yes],
522 + [have_libyajl=no]
523 + )],
524 + [have_libyajl=no]
525 +)
526 +
527 +AC_CHECK_LIB(
528 + [xenstat],
529 + [xenstat_init],
530 + [AC_CHECK_HEADER(
531 + [xenstat.h],
532 + [have_libxenstat=yes],
533 + [have_libxenstat=no]
534 + )],
535 + [have_libxenstat=no],
536 + [-lyajl]
537 +)
538 +
539 +PKG_CHECK_MODULES(
540 + [XENLIGHT],
541 + [xenlight],
542 + [AC_CHECK_LIB(
543 + [xenlight],
544 + [libxl_domain_info],
545 + [AC_CHECK_HEADER(
546 + [libxl.h],
547 + [have_libxenlight=yes],
548 + [have_libxenlight=no]
549 + )],
550 + [have_libxenlight=no]
551 + )],
552 + [have_libxenlight=no]
553 +)
554 +
555 +test "${enable_plugin_xenstat}" = "yes" -a "${have_libxenstat}" != "yes" && \
556 + AC_MSG_ERROR([libxenstat required but not found. try installing 'xen-dom0-libs-devel'])
557 +
558 +test "${enable_plugin_xenstat}" = "yes" -a "${have_libxenlight}" != "yes" && \
559 + AC_MSG_ERROR([libxenlight required but not found. try installing 'xen-dom0-libs-devel'])
560 +
561 +test "${enable_plugin_xenstat}" = "yes" -a "${have_libyajl}" != "yes" && \
562 + AC_MSG_ERROR([libyajl required but not found. Try installing 'yajl-devel'])
563 +
564 +AC_MSG_CHECKING([if xenstat.plugin should be enabled])
565 +if test "${enable_plugin_xenstat}" != "no" -a "${have_libxenstat}" = "yes" -a "${have_libxenlight}" = "yes" -a "${have_libyajl}" = "yes"; then
566 + enable_plugin_xenstat="yes"
567 + AC_DEFINE([HAVE_LIBXENSTAT], [1], [libxenstat usability])
568 + AC_DEFINE([HAVE_LIBXENLIGHT], [1], [libxenlight usability])
569 + AC_DEFINE([HAVE_LIBYAJL], [1], [libyajl usability])
570 + OPTIONAL_XENSTAT_CLFAGS="${XENLIGHT_CFLAGS} ${YAJL_CFLAGS}"
571 + OPTIONAL_XENSTAT_LIBS="-lxenstat ${XENLIGHT_LIBS} ${YAJL_LIBS}"
572 +else
573 + enable_plugin_xenstat="no"
574 +fi
575 +AC_MSG_RESULT([${enable_plugin_xenstat}])
576 +AM_CONDITIONAL([ENABLE_PLUGIN_XENSTAT], [test "${enable_plugin_xenstat}" = "yes"])
577 +
578 +
579 # -----------------------------------------------------------------------------
580 # check for setns() - cgroup-network
581
@@ -527,7 +600,7 @@ if test "${enable_lto}" != "no"; then
600 fi
601 if test "${have_lto}" = "yes"; then
602 oCFLAGS="${CFLAGS}"
530 - CFLAGS="${CFLAGS} -flto ${OPTIONAL_MATH_CLFAGS} ${OPTIONAL_NFACCT_CLFAGS} ${OPTIONAL_ZLIB_CLFAGS} ${OPTIONAL_UUID_CLFAGS} ${OPTIONAL_LIBCAP_CFLAGS} ${OPTIONAL_IPMIMONITORING_CFLAGS} ${OPTIONAL_CUPS_CLFAGS}"
603 + CFLAGS="${CFLAGS} -flto ${OPTIONAL_MATH_CLFAGS} ${OPTIONAL_NFACCT_CLFAGS} ${OPTIONAL_ZLIB_CLFAGS} ${OPTIONAL_UUID_CLFAGS} ${OPTIONAL_LIBCAP_CFLAGS} ${OPTIONAL_IPMIMONITORING_CFLAGS} ${OPTIONAL_CUPS_CLFAGS} ${OPTIONAL_XENSTAT_FLAGS}"
604 ac_cv_c_lto_cross_compile="${enable_lto}"
605 test "${ac_cv_c_lto_cross_compile}" != "yes" && ac_cv_c_lto_cross_compile="no"
606 AC_C_LTO
@@ -600,6 +673,8 @@ AC_SUBST([OPTIONAL_IPMIMONITORING_CFLAGS])
673 AC_SUBST([OPTIONAL_IPMIMONITORING_LIBS])
674 AC_SUBST([OPTIONAL_CUPS_CFLAGS])
675 AC_SUBST([OPTIONAL_CUPS_LIBS])
676 +AC_SUBST([OPTIONAL_XENSTAT_CFLAGS])
677 +AC_SUBST([OPTIONAL_XENSTAT_LIBS])
678
679
680 AC_CONFIG_FILES([
@@ -629,6 +704,7 @@ AC_CONFIG_FILES([
704 collectors/python.d.plugin/Makefile
705 collectors/statsd.plugin/Makefile
706 collectors/tc.plugin/Makefile
707 + collectors/xenstat.plugin/Makefile
708 daemon/Makefile
709 database/Makefile
710 diagrams/Makefile
docs/Add-more-charts-to-netdata.md
+13 -1
@@ -20,6 +20,7 @@ To collect non-system metrics, netdata supports a plugin architecture. The follo
20 - **[Mail Servers](#mail-servers)**, like postfix, exim, dovecot
21 - **[File Servers](#file-servers)**, like samba, NFS, ftp, sftp, WebDAV
22 - **[Print Servers](#print-servers)**, like CUPS
23 +- **[Hypervisors](#hypervisors)**, like XenServer, XCP-ng
24 - **[System](#system)**, for processes and other system metrics
25 - **[Sensors](#sensors)**, like temperature, fans speed, voltage, humidity, HDD/SSD S.M.A.R.T attributes
26 - **[Network](#network)**, such as SNMP devices, `fping`, access points, dns_query_time, nfacct
@@ -66,6 +67,7 @@ To control which plugins netdata run, edit `netdata.conf` and check the `[plugin
67 # fping = yes
68 # charts.d = yes
69 # apps = yes
70 + # xenstat = yes
71 ```
72
73 The default for all plugins is the option `enable running new plugins`. So, setting this to `no` will disable all the plugins, except the ones specifically enabled.
@@ -293,11 +295,21 @@ NFS Client|`C`|This is handled entirely by the netdata daemon.<br/>&nbsp;<br/>Co
295 NFS Server|`C`|This is handled entirely by the netdata daemon.<br/>&nbsp;<br/>Configuration: `netdata.conf`, section `[plugin:proc:/proc/net/rpc/nfsd]`.
296 samba|python<br/>v2 or v3|Performance metrics of Samba SMB2 file sharing.<br/>&nbsp;<br/>documentation page: [python.d.plugin module samba](../collectors/python.d.plugin/samba)<br/>netdata plugin: [python.d.plugin](../collectors/python.d.plugin)<br/>plugin module: [samba.chart.py](../collectors/python.d.plugin/samba)<br/>configuration file: [python.d/samba.conf](../collectors/python.d.plugin/samba)|
297
298 +---
299 +
300 ### Print Servers
301
302 application|language|notes|
303 :---------:|:------:|:----|
300 -CUPS|C|Charts metrics of printers, jobs and other cups destinations.<br/>&nbsp;<br/>netdata plugin: cups.plugin
304 +CUPS|C|Charts metrics of printers, jobs and other cups destinations.<br/>&nbsp;<br/>netdata plugin: [cups.plugin](../collectors/cups.plugin)
305 +
306 +---
307 +
308 +### Hypervisors
309 +
310 +application|language|notes|
311 +:---------:|:------:|:----|
312 +xenstat|C|Collects host and domain statistics for XenServer or XCP-ng hypervisors.<br/>&nbsp;<br/>netdata plugin: [xenstat.plugin](../collectors/xenstat.plugin)
313
314 ---
315
docs/generator/buildyaml.sh
+1
@@ -226,6 +226,7 @@ navpart 3 collectors/cups.plugin
226 navpart 3 collectors/fping.plugin
227 navpart 3 collectors/freeipmi.plugin
228 navpart 3 collectors/nfacct.plugin
229 +navpart 3 collectors/xenstat.plugin
230
231
232 echo -ne " - 'docs/Third-Party-Plugins.md'
netdata-installer.sh
+17
@@ -148,6 +148,12 @@ Valid <installer options> are:
148 Enable/disable the nfacct plugin.
149 Default: enable it when libmnl and libnetfilter_acct are available.
150
151 + --enable-plugin-xenstat
152 + --disable-plugin-xenstat
153 +
154 + Enable/disable the xenstat plugin.
155 + Default: enable it when libxenstat and libyajl are available.
156 +
157 --enable-lto
158 --disable-lto
159
@@ -225,6 +231,12 @@ while [ ! -z "${1}" ]; do
231 elif [ "$1" = "--disable-plugin-nfacct" ]; then
232 NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS//--disable-plugin-nfacct/} --disable-plugin-nfacct"
233 shift 1
234 + elif [ "$1" = "--enable-plugin-xenstat" ]; then
235 + NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS//--enable-plugin-xenstat/} --enable-plugin-xenstat"
236 + shift 1
237 + elif [ "$1" = "--disable-plugin-xenstat" ]; then
238 + NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS//--disable-plugin-xenstat/} --disable-plugin-xenstat"
239 + shift 1
240 elif [ "$1" = "--enable-lto" ]; then
241 NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS//--enable-lto/} --enable-lto"
242 shift 1
@@ -771,6 +783,11 @@ if [ ${UID} -eq 0 ]; then
783 run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/nfacct.plugin"
784 fi
785
786 + if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin" ]; then
787 + run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin"
788 + run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/xenstat.plugin"
789 + fi
790 +
791 if [ -f "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network" ]; then
792 run chown root:${NETDATA_GROUP} "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network"
793 run chmod 4750 "${NETDATA_PREFIX}/usr/libexec/netdata/plugins.d/cgroup-network"
web/gui/dashboard_info.js
+12
@@ -443,6 +443,18 @@ netdataDashboard.menu = {
443 title: 'Power Supply',
444 icon: '<i class="fas fa-battery-half"></i>',
445 info: 'Statistics for the various system power supplies. Data collected from <a href="https://www.kernel.org/doc/Documentation/power/power_supply_class.txt">Linux power supply class</a>.'
446 + },
447 +
448 + 'xenstat': {
449 + title: 'Xen Node',
450 + icon: '<i class="fas fa-server"></i>',
451 + info: 'General statistics for the Xen node. Data collected using <b>xenstat</b> library</a>.'
452 + },
453 +
454 + 'xendomain': {
455 + title: '',
456 + icon: '<i class="fas fa-th-large"></i>',
457 + info: 'Xen domain resource utilization metrics. Netdata reads this information using <b>xenstat</b> library which gives access to the resource usage information (CPU, memory, disk I/O, network) for a virtual machine.'
458 }
459 };
460