rrd based system stats
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hddtemp.c 5.2 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /***************************************************************************
  2. * Copyright (C) 12/2012 by Olaf Rempel *
  3. * razzor@kopf-tisch.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include <sys/socket.h>
  25. #include <sys/types.h>
  26. #include <sys/un.h>
  27. #include "configfile.h"
  28. #include "helper.h"
  29. #include "list.h"
  30. #include "logging.h"
  31. #include "plugins.h"
  32. #include "probe.h"
  33. #include "sockaddr.h"
  34. #define RESP_SIZE 1024
  35. struct sammler_plugin plugin;
  36. struct server_entry {
  37. struct list_head list;
  38. char *name;
  39. int errors;
  40. struct sockaddr_in sa;
  41. };
  42. static LIST_HEAD(server_list);
  43. static char *resp_buf;
  44. static const char *ds_def = {
  45. "DS:temperature:GAUGE:90:0:100"
  46. };
  47. static const char * get_ds(int ds_id)
  48. {
  49. return ds_def;
  50. }
  51. static int probe(void)
  52. {
  53. struct server_entry *entry;
  54. list_for_each_entry(entry, &server_list, list) {
  55. int sock = socket(AF_INET, SOCK_STREAM, 0);
  56. if (sock == -1) {
  57. log_print(LOG_WARN, "%s: socket()", plugin.name);
  58. continue;
  59. }
  60. int ret = connect(sock, (struct sockaddr *)&entry->sa, sizeof(entry->sa));
  61. if (ret != 0) {
  62. if (entry->errors++ == 0)
  63. log_print(LOG_ERROR, "%s: connect(%s)", plugin.name, get_sockaddr_buf(&entry->sa));
  64. close(sock);
  65. continue;
  66. }
  67. int pos = 0;
  68. int len;
  69. do {
  70. len = read(sock, resp_buf + pos, RESP_SIZE - pos);
  71. if ((pos == 0) && (len <= 0)) {
  72. if (entry->errors++ == 0)
  73. log_print(LOG_ERROR, "%s: read()", plugin.name);
  74. break;
  75. }
  76. pos += len;
  77. } while (len > 0);
  78. close(sock);
  79. if (pos == 0)
  80. continue;
  81. resp_buf[pos] = '\0';
  82. /* '|/dev/sda|OCZ-VERTEX3|128|C||/dev/sdb|HDT722525DLA380|SLP|*||/dev/sdc|Generic STORAGE DEVICE|NA|*|' */
  83. char *tok, *tmp = NULL, *resp = resp_buf;
  84. int i = 0;
  85. char *device = NULL;
  86. int temperature = 0;
  87. while ((tok = strtok_r(resp, "|", &tmp)) != NULL) {
  88. if ((i % 4) == 0) {
  89. device = strrchr(tok, '/');
  90. if (device != NULL && *(device +1) == '\0')
  91. device = NULL;
  92. else
  93. device++;
  94. } else if ((i % 4) == 2) {
  95. char *tmp2;
  96. temperature = strtol(tok, &tmp2, 10);
  97. if (*tmp2 != '\0')
  98. device = NULL;
  99. } else if ((i % 4) == 3) {
  100. if ((tok[0] == 'C') && (device != NULL)) {
  101. char filename[32];
  102. len = snprintf(filename, sizeof(filename), "%s-%s.rrd", plugin.name, device);
  103. if (len < 0 || len >= sizeof(filename))
  104. continue;
  105. probe_submit(&plugin, filename, 0, "%d", temperature);
  106. }
  107. device = NULL;
  108. temperature = 0;
  109. }
  110. i++;
  111. resp = NULL;
  112. }
  113. if (entry->errors > 0) {
  114. log_print(LOG_ERROR, "%s: success (%s) after %d errors",
  115. plugin.name, entry->name, entry->errors);
  116. entry->errors = 0;
  117. }
  118. }
  119. return 0;
  120. }
  121. static int init_cb(struct strtoken *tokens, void *privdata)
  122. {
  123. if (tokens->count != 2) {
  124. log_print(LOG_ERROR, "%s: parse error", plugin.name);
  125. return -1;
  126. }
  127. struct server_entry *entry = malloc(sizeof(struct server_entry));
  128. if (entry == NULL) {
  129. log_print(LOG_ERROR, "%s: out of memory", plugin.name);
  130. return -1;
  131. }
  132. entry->name = strdup(tokens->field[0]);
  133. entry->errors = 0;
  134. if (parse_sockaddr(tokens->field[1], &entry->sa) < 0) {
  135. log_print(LOG_ERROR, "%s: invalid address: <%s>", plugin.name, tokens->field[1]);
  136. free(entry->name);
  137. free(entry);
  138. return -1;
  139. }
  140. log_print(LOG_INFO, "%s: added server '%s'", plugin.name, entry->name);
  141. list_add_tail(&entry->list, &server_list);
  142. return 0;
  143. }
  144. static int init(void)
  145. {
  146. resp_buf = malloc(RESP_SIZE);
  147. if (resp_buf == NULL) {
  148. log_print(LOG_ERROR, "%s: out of memory", plugin.name);
  149. return -1;
  150. }
  151. config_get_strtokens("p_hddtemp", "server", ",", 2, init_cb, NULL);
  152. return 0;
  153. }
  154. static int fini(void)
  155. {
  156. struct server_entry *entry, *tmp;
  157. list_for_each_entry_safe(entry, tmp, &server_list, list) {
  158. free(entry->name);
  159. free(entry);
  160. }
  161. free(resp_buf);
  162. return 0;
  163. }
  164. struct sammler_plugin plugin = {
  165. .name = "hddtemp",
  166. .interval = 60,
  167. .init = &init,
  168. .fini = &fini,
  169. .probe = &probe,
  170. .get_ds = &get_ds,
  171. };