/** * collectd - src/drbd.c * Copyright (C) 2014 Tim Laszlo * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Authors: * Tim Laszlo **/ /* See: http://www.drbd.org/users-guide/ch-admin.html#s-performance-indicators version: 8.3.11 (api:88/proto:86-96) srcversion: 71955441799F513ACA6DA60 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate B r----- ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \ pe:0 ua:0 ap:0 ep:1 wo:f oos:0 */ #include "collectd.h" #include "plugin.h" #include "utils/common/common.h" static const char *drbd_stats = "/proc/drbd"; static const char *drbd_names[] = { "network_send", /* ns (network send) */ "network_recv", /* nr (network receive) */ "disk_write", /* dw (disk write) */ "disk_read", /* dr (disk read) */ "activity_log", /* al (activity log) */ "bitmap", /* bm (bit map) */ "local_count", /* lo (local count) */ "pending", /* pe (pending) */ "unacknowledged", /* ua (unacknowledged) */ "app pending", /* ap (application pending) */ "epochs", /* ep (epochs) */ NULL, /* wo (write order) */ "oos" /* oos (out of sync) */ }; static size_t drbd_names_num = STATIC_ARRAY_SIZE(drbd_names); static int drbd_init(void) { return 0; } static int drbd_submit_fields(long int resource, char **fields, size_t fields_num) { char plugin_instance[DATA_MAX_NAME_LEN]; value_t values[fields_num]; value_list_t vl = VALUE_LIST_INIT; if (resource < 0) { WARNING("drbd plugin: Unable to parse resource"); return EINVAL; } if (fields_num != drbd_names_num) { WARNING("drbd plugin: Wrong number of fields for " "r%ld statistics. Expected %" PRIsz ", got %" PRIsz ".", resource, drbd_names_num, fields_num); return EINVAL; } snprintf(plugin_instance, sizeof(plugin_instance), "r%ld", resource); for (size_t i = 0; i < drbd_names_num; i++) { char *data; /* skip non numeric wo */ if (strncmp(fields[i], "wo", 2) == 0) continue; data = strchr(fields[i], ':'); if (data == NULL) return EINVAL; (void)parse_value(++data, &values[i], DS_TYPE_DERIVE); } vl.values_len = 1; sstrncpy(vl.plugin, "drbd", sizeof(vl.plugin)); sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); sstrncpy(vl.type, "drbd_resource", sizeof(vl.type)); for (size_t i = 0; i < fields_num; i++) { if (drbd_names[i] == NULL) continue; vl.values = values + i; sstrncpy(vl.type_instance, drbd_names[i], sizeof(vl.type_instance)); plugin_dispatch_values(&vl); } return 0; } /* drbd_submit_fields */ static int drbd_read(void) { FILE *fh; char buffer[256]; long int resource = -1; char *fields[16]; int fields_num = 0; fh = fopen(drbd_stats, "r"); if (fh == NULL) { WARNING("drbd plugin: Unable to open %s", drbd_stats); return EINVAL; } while (fgets(buffer, sizeof(buffer), fh) != NULL) { fields_num = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); /* ignore headers (first two iterations) */ if ((strcmp(fields[0], "version:") == 0) || (strcmp(fields[0], "srcversion:") == 0) || (strcmp(fields[0], "GIT-hash:") == 0)) { continue; } if (isdigit(fields[0][0])) { /* parse the resource line, next loop iteration will submit values for this resource */ resource = strtol(fields[0], NULL, 10); } else { /* handle stats data for the resource defined in the previous iteration */ drbd_submit_fields(resource, fields, fields_num); } } /* while (fgets) */ fclose(fh); return 0; } /* void drbd_read */ void module_register(void) { plugin_register_init("drbd", drbd_init); plugin_register_read("drbd", drbd_read); } /* void module_register */