Changeset 7d308b7989cb04229e214e3ca04435922d9965c8
- Timestamp:
- 02/16/11 01:41:23
(2 years ago)
- Author:
- Theo Schlossnagle <jesus@omniti.com>
- git-committer:
- Theo Schlossnagle <jesus@omniti.com> 1297820483 +0000
- git-parent:
[b7a4679e0291d61725dbbb87147645140ae8c802]
- git-author:
- Theo Schlossnagle <jesus@omniti.com> 1297820483 +0000
- Message:
make collect work better and support watches
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| rf9aada0 |
r7d308b7 |
|
| 47 | 47 | static noit_log_stream_t nlerr = NULL; |
|---|
| 48 | 48 | static noit_log_stream_t nldeb = NULL; |
|---|
| 49 | | static int __collectd_initialize_once = 0; |
|---|
| 50 | | |
|---|
| 51 | 49 | |
|---|
| 52 | 50 | typedef struct _mod_config { |
|---|
| 53 | 51 | noit_hash_table *options; |
|---|
| 54 | 52 | noit_hash_table target_sessions; |
|---|
| | 53 | noit_boolean support_notifications; |
|---|
| 55 | 54 | int ipv4_fd; |
|---|
| 56 | 55 | int ipv6_fd; |
|---|
| … | … | |
| 113 | 112 | #define NET_DEFAULT_V4_ADDR "239.192.74.66" |
|---|
| 114 | 113 | #define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42" |
|---|
| 115 | | #define NET_DEFAULT_PORT "25826" |
|---|
| | 114 | #define NET_DEFAULT_PORT 25826 |
|---|
| 116 | 115 | |
|---|
| 117 | 116 | #define TYPE_HOST 0x0000 |
|---|
| … | … | |
| 1166 | 1165 | char buf[20]; |
|---|
| 1167 | 1166 | snprintf(buf, sizeof(buf), "%d", index); |
|---|
| 1168 | | strcat(buffer, buf); |
|---|
| | 1167 | strcat(buffer, buf); |
|---|
| 1169 | 1168 | noitL(noit_debug, "collectd: parsing multiple values" |
|---|
| 1170 | 1169 | " and guessing on the type for plugin[%s] and type[%s]" |
|---|
| … | … | |
| 1195 | 1194 | stats_t current; |
|---|
| 1196 | 1195 | char buffer[DATA_MAX_NAME_LEN*4 + 128]; |
|---|
| | 1196 | collectd_mod_config_t *conf; |
|---|
| | 1197 | conf = noit_module_get_userdata(self); |
|---|
| | 1198 | |
|---|
| | 1199 | if(!conf->support_notifications) return 0; |
|---|
| | 1200 | /* We are passive, so we don't do anything for transient checks */ |
|---|
| | 1201 | if(check->flags & NP_TRANSIENT) return 0; |
|---|
| 1197 | 1202 | |
|---|
| 1198 | 1203 | noit_check_stats_clear(¤t); |
|---|
| 1199 | 1204 | gettimeofday(¤t.whence, NULL); |
|---|
| | 1205 | |
|---|
| 1200 | 1206 | // Concat all the names together so they fit into the flat noitd model |
|---|
| 1201 | 1207 | concat_metrics(buffer, n->plugin, n->plugin_instance, n->type, n->type_instance); |
|---|
| 1202 | 1208 | noit_stats_set_metric(&ccl->current, buffer, METRIC_STRING, n->message); |
|---|
| 1203 | | noit_check_set_stats(self, check, ¤t); |
|---|
| | 1209 | noit_check_passive_set_stats(self, check, ¤t); |
|---|
| 1204 | 1210 | noitL(nldeb, "collectd: dispatch_notifications(%s, %s, %s)\n",check->target, buffer, n->message); |
|---|
| 1205 | 1211 | return 0; |
|---|
| … | … | |
| 1250 | 1256 | noitL(nldeb, "collectd: queue_values(%s, %s)\n", buffer, check->target); |
|---|
| 1251 | 1257 | } |
|---|
| 1252 | | //noit_check_set_stats(self, check, ¤t); |
|---|
| 1253 | 1258 | return 0; |
|---|
| 1254 | 1259 | } |
|---|
| … | … | |
| 1264 | 1269 | collectd_closure_t *ccl; |
|---|
| 1265 | 1270 | struct timeval duration; |
|---|
| | 1271 | /* We are passive, so we don't do anything for transient checks */ |
|---|
| | 1272 | if(check->flags & NP_TRANSIENT) return 0; |
|---|
| | 1273 | |
|---|
| 1266 | 1274 | if(!check->closure) { |
|---|
| 1267 | 1275 | ccl = check->closure = (void *)calloc(1, sizeof(collectd_closure_t)); |
|---|
| … | … | |
| 1286 | 1294 | NP_GOOD : NP_BAD; |
|---|
| 1287 | 1295 | ccl->current.status = human_buffer; |
|---|
| 1288 | | noit_check_set_stats(self, check, &ccl->current); |
|---|
| | 1296 | noit_check_passive_set_stats(self, check, &ccl->current); |
|---|
| 1289 | 1297 | |
|---|
| 1290 | 1298 | memcpy(&check->last_fire_time, &ccl->current.whence, sizeof(duration)); |
|---|
| … | … | |
| 1296 | 1304 | static int noit_collectd_handler(eventer_t e, int mask, void *closure, |
|---|
| 1297 | 1305 | struct timeval *now) { |
|---|
| 1298 | | struct sockaddr_in skaddr; |
|---|
| | 1306 | union { |
|---|
| | 1307 | struct sockaddr_in skaddr; |
|---|
| | 1308 | struct sockaddr_in6 skaddr6; |
|---|
| | 1309 | } remote; |
|---|
| 1299 | 1310 | char packet[1500]; |
|---|
| 1300 | 1311 | int packet_len = sizeof(packet); |
|---|
| 1301 | 1312 | unsigned int from_len; |
|---|
| 1302 | | char ip_p[INET_ADDRSTRLEN]; |
|---|
| | 1313 | char ip_p[INET6_ADDRSTRLEN]; |
|---|
| 1303 | 1314 | noit_module_t *self = (noit_module_t *)closure; |
|---|
| 1304 | 1315 | collectd_mod_config_t *conf; |
|---|
| … | … | |
| 1314 | 1325 | char *security_buffer; |
|---|
| 1315 | 1326 | |
|---|
| 1316 | | from_len = sizeof(skaddr); |
|---|
| | 1327 | from_len = sizeof(remote); |
|---|
| 1317 | 1328 | |
|---|
| 1318 | 1329 | inlen = recvfrom(e->fd, packet, packet_len, 0, |
|---|
| 1319 | | (struct sockaddr *)&skaddr, &from_len); |
|---|
| | 1330 | (struct sockaddr *)&remote, &from_len); |
|---|
| 1320 | 1331 | gettimeofday(now, NULL); /* set it, as we care about accuracy */ |
|---|
| 1321 | 1332 | |
|---|
| … | … | |
| 1325 | 1336 | break; |
|---|
| 1326 | 1337 | } |
|---|
| 1327 | | if (!inet_ntop(AF_INET, &(skaddr.sin_addr), ip_p, INET_ADDRSTRLEN)) { |
|---|
| 1328 | | noitLT(nlerr, now, "collectd: inet_ntop failed: %s\n", strerror(errno)); |
|---|
| | 1338 | if (from_len == sizeof(remote.skaddr)) { |
|---|
| | 1339 | if (!inet_ntop(AF_INET, &(remote.skaddr.sin_addr), ip_p, INET_ADDRSTRLEN)) { |
|---|
| | 1340 | noitLT(nlerr, now, "collectd: inet_ntop failed: %s\n", strerror(errno)); |
|---|
| | 1341 | break; |
|---|
| | 1342 | } |
|---|
| | 1343 | } |
|---|
| | 1344 | else if(from_len == sizeof(remote.skaddr6)) { |
|---|
| | 1345 | if (!inet_ntop(AF_INET6, &(remote.skaddr6.sin6_addr), ip_p, INET6_ADDRSTRLEN)) { |
|---|
| | 1346 | noitLT(nlerr, now, "collectd: inet_ntop failed: %s\n", strerror(errno)); |
|---|
| | 1347 | break; |
|---|
| | 1348 | } |
|---|
| | 1349 | } |
|---|
| | 1350 | else { |
|---|
| | 1351 | noitLT(nlerr, now, "collectd: could not determine address family of remote\n"); |
|---|
| 1329 | 1352 | break; |
|---|
| 1330 | 1353 | } |
|---|
| … | … | |
| 1341 | 1364 | memset(ccl, 0, sizeof(collectd_closure_t)); |
|---|
| 1342 | 1365 | } else { |
|---|
| 1343 | | ccl = (collectd_closure_t*)check->closure; |
|---|
| | 1366 | ccl = (collectd_closure_t*)check->closure; |
|---|
| 1344 | 1367 | } |
|---|
| 1345 | 1368 | // Default to NONE |
|---|
| 1346 | | ccl->security_level = SECURITY_LEVEL_NONE; |
|---|
| | 1369 | ccl->security_level = SECURITY_LEVEL_NONE; |
|---|
| 1347 | 1370 | if (noit_hash_retr_str(check->config, "security_level", strlen("security_level"), |
|---|
| 1348 | 1371 | (const char**)&security_buffer)) |
|---|
| … | … | |
| 1421 | 1444 | if(!nlerr) nlerr = noit_log_stream_find("error/collectd"); |
|---|
| 1422 | 1445 | if(!nldeb) nldeb = noit_log_stream_find("debug/collectd"); |
|---|
| 1423 | | if(!nlerr) nlerr = noit_stderr; |
|---|
| | 1446 | if(!nlerr) nlerr = noit_error; |
|---|
| 1424 | 1447 | if(!nldeb) nldeb = noit_debug; |
|---|
| 1425 | 1448 | eventer_name_callback("noit_collectd/handler", noit_collectd_handler); |
|---|
| … | … | |
| 1434 | 1457 | int portint = 0; |
|---|
| 1435 | 1458 | struct sockaddr_in skaddr; |
|---|
| | 1459 | struct sockaddr_in6 skaddr6; |
|---|
| | 1460 | struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; |
|---|
| 1436 | 1461 | const char *host; |
|---|
| 1437 | 1462 | unsigned short port; |
|---|
| 1438 | 1463 | |
|---|
| 1439 | | if(!__collectd_initialize_once) { |
|---|
| 1440 | | __collectd_initialize_once = 1; |
|---|
| 1441 | | } |
|---|
| 1442 | | |
|---|
| 1443 | | |
|---|
| | 1464 | conf->support_notifications = noit_true; |
|---|
| | 1465 | if(noit_hash_retr_str(conf->options, |
|---|
| | 1466 | "notifications", strlen("notifications"), |
|---|
| | 1467 | (const char **)&config_val)) { |
|---|
| | 1468 | if(!strcasecmp(config_val, "false") || !strcasecmp(config_val, "off")) |
|---|
| | 1469 | conf->support_notifications = noit_false; |
|---|
| | 1470 | } |
|---|
| 1444 | 1471 | /* Default Collectd port */ |
|---|
| 1445 | | portint = 25826; |
|---|
| | 1472 | portint = NET_DEFAULT_PORT; |
|---|
| 1446 | 1473 | if(noit_hash_retr_str(conf->options, |
|---|
| 1447 | 1474 | "collectd_port", strlen("collectd_port"), |
|---|
| … | … | |
| 1465 | 1492 | } |
|---|
| 1466 | 1493 | else { |
|---|
| 1467 | | /* |
|---|
| 1468 | | socklen_t slen = sizeof(on); |
|---|
| 1469 | | if(getsockopt(conf->ipv4_fd, SOL_SOCKET, SO_SNDBUF, &on, &slen) == 0) { |
|---|
| 1470 | | while(on < (1 << 20)) { |
|---|
| 1471 | | on <<= 1; |
|---|
| 1472 | | if(setsockopt(conf->ipv4_fd, SOL_SOCKET, SO_SNDBUF, |
|---|
| 1473 | | &on, sizeof(on)) != 0) { |
|---|
| 1474 | | on >>= 1; |
|---|
| 1475 | | break; |
|---|
| 1476 | | } |
|---|
| 1477 | | } |
|---|
| 1478 | | noitL(noit_debug, ": send buffer set to %d\n", on); |
|---|
| 1479 | | } |
|---|
| 1480 | | else |
|---|
| 1481 | | noitL(noit_error, "Cannot get sndbuf size: %s\n", strerror(errno)); |
|---|
| 1482 | | */ |
|---|
| 1483 | 1494 | if(eventer_set_fd_nonblocking(conf->ipv4_fd)) { |
|---|
| 1484 | 1495 | close(conf->ipv4_fd); |
|---|
| … | … | |
| 1495 | 1506 | sockaddr_len = sizeof(skaddr); |
|---|
| 1496 | 1507 | if(bind(conf->ipv4_fd, (struct sockaddr *)&skaddr, sockaddr_len) < 0) { |
|---|
| 1497 | | noitL(noit_stderr, "bind failed[%s]: %s\n", host, strerror(errno)); |
|---|
| | 1508 | noitL(noit_error, "bind failed[%s]: %s\n", host, strerror(errno)); |
|---|
| 1498 | 1509 | close(conf->ipv4_fd); |
|---|
| 1499 | 1510 | return -1; |
|---|
| … | … | |
| 1509 | 1520 | eventer_add(newe); |
|---|
| 1510 | 1521 | } |
|---|
| 1511 | | /* |
|---|
| | 1522 | |
|---|
| 1512 | 1523 | conf->ipv6_fd = socket(AF_INET6, SOCK_DGRAM, 0); |
|---|
| 1513 | 1524 | if(conf->ipv6_fd < 0) { |
|---|
| 1514 | | noitL(noit_error, "collectd: socket failed: %s\n", |
|---|
| | 1525 | noitL(noit_error, "collectd: IPv6 socket failed: %s\n", |
|---|
| 1515 | 1526 | strerror(errno)); |
|---|
| 1516 | 1527 | } |
|---|
| … | … | |
| 1524 | 1535 | } |
|---|
| 1525 | 1536 | } |
|---|
| | 1537 | sockaddr_len = sizeof(skaddr6); |
|---|
| | 1538 | memset(&skaddr6, 0, sizeof(skaddr6)); |
|---|
| | 1539 | skaddr6.sin6_family = AF_INET6; |
|---|
| | 1540 | skaddr6.sin6_addr = in6addr_any; |
|---|
| | 1541 | skaddr6.sin6_port = htons(port); |
|---|
| | 1542 | |
|---|
| | 1543 | if(bind(conf->ipv6_fd, (struct sockaddr *)&skaddr6, sockaddr_len) < 0) { |
|---|
| | 1544 | noitL(noit_error, "bind(IPv6) failed[%s]: %s\n", host, strerror(errno)); |
|---|
| | 1545 | close(conf->ipv6_fd); |
|---|
| | 1546 | conf->ipv6_fd = -1; |
|---|
| | 1547 | } |
|---|
| | 1548 | |
|---|
| 1526 | 1549 | if(conf->ipv6_fd >= 0) { |
|---|
| 1527 | 1550 | eventer_t newe; |
|---|
| … | … | |
| 1529 | 1552 | newe->fd = conf->ipv6_fd; |
|---|
| 1530 | 1553 | newe->mask = EVENTER_READ; |
|---|
| 1531 | | newe->callback = ping_icmp_handler; |
|---|
| | 1554 | newe->callback = noit_collectd_handler; |
|---|
| 1532 | 1555 | newe->closure = self; |
|---|
| 1533 | 1556 | eventer_add(newe); |
|---|
| 1534 | 1557 | } |
|---|
| 1535 | | */ |
|---|
| | 1558 | |
|---|
| 1536 | 1559 | noit_module_set_userdata(self, conf); |
|---|
| 1537 | 1560 | return 0; |
|---|
| r6c61339 |
r7d308b7 |
|
| 3 | 3 | <description><para>The collectd module provides collectd support for Reconnoiter. The collectd modules listens on a UDP port and waits for metrics to come from a collectd agent. It also provides support for signing and encrypting metrics from the collectd agent, which is supported in version 4.7.0 and above. Only one is supported per target.</para></description> |
|---|
| 4 | 4 | <loader>C</loader> |
|---|
| 5 | | <image>snmp.so</image> |
|---|
| | 5 | <image>collectd.so</image> |
|---|
| 6 | 6 | <moduleconfig> |
|---|
| 7 | 7 | <parameter name="collectd_port" |
|---|
| … | … | |
| 9 | 9 | default="25826" |
|---|
| 10 | 10 | allowed="\d+">The port which collectd packets are received</parameter> |
|---|
| 11 | | <parameter name="snmptrapd_host" |
|---|
| 12 | | required="optional" |
|---|
| 13 | | default="*" |
|---|
| 14 | | allowed="\d+">The host interface on which packets are accepted.</parameter> |
|---|
| | 11 | <parameter name="notifications" |
|---|
| | 12 | required="options" |
|---|
| | 13 | default="true" |
|---|
| | 14 | allowed="(?:true|on|false|off)">Specify whether collectd notifications are acted upon.</parameter> |
|---|
| 15 | 15 | </moduleconfig> |
|---|
| 16 | 16 | <checkconfig> |
|---|
| r6851033 |
r7d308b7 |
|
| 1012 | 1012 | |
|---|
| 1013 | 1013 | void |
|---|
| | 1014 | noit_check_passive_set_stats(struct _noit_module *module, |
|---|
| | 1015 | noit_check_t *check, stats_t *newstate) { |
|---|
| | 1016 | noit_skiplist_node *next; |
|---|
| | 1017 | noit_check_t n; |
|---|
| | 1018 | |
|---|
| | 1019 | uuid_copy(n.checkid, check->checkid); |
|---|
| | 1020 | n.period = 0; |
|---|
| | 1021 | |
|---|
| | 1022 | noit_check_set_stats(module,check,newstate); |
|---|
| | 1023 | noit_skiplist_find_neighbors(&watchlist, &n, NULL, NULL, &next); |
|---|
| | 1024 | while(next && next->data) { |
|---|
| | 1025 | stats_t backup; |
|---|
| | 1026 | noit_check_t *wcheck = next->data; |
|---|
| | 1027 | if(uuid_compare(n.checkid, wcheck->checkid)) break; |
|---|
| | 1028 | |
|---|
| | 1029 | /* Swap the real check's stats into place */ |
|---|
| | 1030 | memcpy(&backup, &wcheck->stats.current, sizeof(stats_t)); |
|---|
| | 1031 | memcpy(&wcheck->stats.current, newstate, sizeof(stats_t)); |
|---|
| | 1032 | /* Write out our status */ |
|---|
| | 1033 | noit_check_log_status(wcheck); |
|---|
| | 1034 | /* Write out all metrics */ |
|---|
| | 1035 | noit_check_log_metrics(wcheck); |
|---|
| | 1036 | /* Swap them back out */ |
|---|
| | 1037 | memcpy(&wcheck->stats.current, &backup, sizeof(stats_t)); |
|---|
| | 1038 | |
|---|
| | 1039 | noit_skiplist_next(&watchlist, &next); |
|---|
| | 1040 | } |
|---|
| | 1041 | } |
|---|
| | 1042 | void |
|---|
| 1014 | 1043 | noit_check_set_stats(struct _noit_module *module, |
|---|
| 1015 | 1044 | noit_check_t *check, stats_t *newstate) { |
|---|
| rb553f9a |
r7d308b7 |
|
| 217 | 217 | |
|---|
| 218 | 218 | struct _noit_module; |
|---|
| | 219 | /* This if for modules (passive) than cannot be watched... */ |
|---|
| | 220 | API_EXPORT(void) |
|---|
| | 221 | noit_check_passive_set_stats(struct _noit_module *self, noit_check_t *check, |
|---|
| | 222 | stats_t *newstate); |
|---|
| | 223 | /* This is for normal (active) modules... */ |
|---|
| 219 | 224 | API_EXPORT(void) |
|---|
| 220 | 225 | noit_check_set_stats(struct _noit_module *self, noit_check_t *check, |
|---|