f4105579efa5321aca7f226abb69b8871aa826dc
1 /**
2 * collectd - src/drbd.c
3 * Copyright (C) 2014 Tim Laszlo
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Authors:
19 * Tim Laszlo <tim.laszlo at gmail.com>
20 **/
22 /*
23 See: http://www.drbd.org/users-guide/ch-admin.html#s-performance-indicators
25 version: 8.3.11 (api:88/proto:86-96)
26 srcversion: 71955441799F513ACA6DA60
27 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate B r-----
28 ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \
29 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
30 */
32 #include "collectd.h"
33 #include "common.h"
34 #include "plugin.h"
36 static const char *drbd_stats = "/proc/drbd";
37 static const char *drbd_names[] =
38 {
39 "network_send", /* ns (network send) */
40 "network_recv", /* nr (network receive) */
41 "disk_write", /* dw (disk write) */
42 "disk_read", /* dr (disk read) */
43 "activity_log", /* al (activity log) */
44 "bitmap", /* bm (bit map) */
45 "local_count", /* lo (local count) */
46 "pending", /* pe (pending) */
47 "unacknowledged", /* ua (unacknowledged) */
48 "app pending", /* ap (application pending) */
49 "epochs", /* ep (epochs) */
50 NULL, /* wo (write order) */
51 "oos" /* oos (out of sync) */
52 };
53 static size_t drbd_names_num = STATIC_ARRAY_SIZE (drbd_names);
55 static int drbd_init (void)
56 {
57 return (0);
58 }
61 static int drbd_submit_fields (long int resource,
62 char **fields, size_t fields_num)
63 {
64 char plugin_instance[DATA_MAX_NAME_LEN];
65 value_t values[fields_num];
66 value_list_t vl = VALUE_LIST_INIT;
67 size_t i;
69 if (resource < 0)
70 {
71 WARNING ("drbd plugin: Unable to parse resource");
72 return (EINVAL);
73 }
75 if (fields_num != drbd_names_num)
76 {
77 WARNING ("drbd plugin: Wrong number of fields for "
78 "r%ld statistics. Expected %zu, got %zu.",
79 resource, drbd_names_num, fields_num);
80 return (EINVAL);
81 }
83 ssnprintf (plugin_instance, sizeof (plugin_instance), "r%ld",
84 resource);
86 for (i = 0; i < drbd_names_num; i++)
87 {
88 char *data;
89 /* skip non numeric wo */
90 if (strncmp(fields[i], "wo", 2) == 0)
91 continue;
92 data = strchr(fields[i], ':');
93 if (data == NULL)
94 return (EINVAL);
95 (void) parse_value (++data, &values[i], DS_TYPE_DERIVE);
96 }
98 vl.values_len = 1;
99 sstrncpy (vl.host, hostname_g, sizeof (vl.host));
100 sstrncpy (vl.plugin, "drbd", sizeof (vl.plugin));
101 sstrncpy (vl.plugin_instance, plugin_instance,
102 sizeof (vl.plugin_instance));
103 sstrncpy (vl.type, "drbd_resource", sizeof (vl.type));
105 for (i = 0; i < fields_num; i++)
106 {
107 if (drbd_names[i] == NULL)
108 continue;
109 vl.values = values + i;
110 sstrncpy (vl.type_instance, drbd_names[i],
111 sizeof (vl.type_instance));
112 plugin_dispatch_values (&vl);
113 }
115 return (0);
116 } /* drbd_submit_fields */
118 static int drbd_read (void)
119 {
120 FILE *fh;
121 char buffer[256];
123 long int resource = -1;
124 char *fields[16];
125 int fields_num = 0;
127 fh = fopen (drbd_stats, "r");
128 if (fh == NULL)
129 {
130 WARNING ("Unable to open%s", drbd_stats);
131 return (EINVAL);
132 }
134 while (fgets (buffer, sizeof (buffer), fh) != NULL)
135 {
136 fields_num = strsplit (buffer,
137 fields, STATIC_ARRAY_SIZE (fields));
139 /* ignore headers (first two iterations) */
140 if (fields_num < 4)
141 continue;
143 if (isdigit(fields[0][0]))
144 {
145 /* parse the resource line, next loop iteration
146 will submit values for this resource */
147 resource = strtol(fields[0], NULL, 10);
148 }
149 else
150 {
151 /* handle stats data for the resource defined in the
152 previous iteration */
153 drbd_submit_fields(resource, fields, fields_num);
154 }
155 } /* while (fgets) */
157 fclose (fh);
158 return (0);
159 } /* void drbd_read */
161 void module_register (void)
162 {
163 plugin_register_init ("drbd", drbd_init);
164 plugin_register_read ("drbd", drbd_read);
165 } /* void module_register */