Changeset 7d308b7989cb04229e214e3ca04435922d9965c8

Show
Ignore:
Timestamp:
02/16/11 01:41:23 (3 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
  • src/modules/collectd.c

    rf9aada0 r7d308b7  
    4747static noit_log_stream_t nlerr = NULL; 
    4848static noit_log_stream_t nldeb = NULL; 
    49 static int __collectd_initialize_once = 0; 
    50  
    5149 
    5250typedef struct _mod_config { 
    5351  noit_hash_table *options; 
    5452  noit_hash_table target_sessions; 
     53  noit_boolean support_notifications; 
    5554  int ipv4_fd; 
    5655  int ipv6_fd; 
     
    113112#define NET_DEFAULT_V4_ADDR "239.192.74.66" 
    114113#define NET_DEFAULT_V6_ADDR "ff18::efc0:4a42" 
    115 #define NET_DEFAULT_PORT    "25826" 
     114#define NET_DEFAULT_PORT    25826 
    116115 
    117116#define TYPE_HOST            0x0000 
     
    11661165    char buf[20]; 
    11671166    snprintf(buf, sizeof(buf), "%d", index); 
    1168     strcat(buffer, buf);  
     1167    strcat(buffer, buf); 
    11691168    noitL(noit_debug, "collectd: parsing multiple values"  
    11701169        " and guessing on the type for plugin[%s] and type[%s]" 
     
    11951194  stats_t current; 
    11961195  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; 
    11971202 
    11981203  noit_check_stats_clear(&current); 
    11991204  gettimeofday(&current.whence, NULL); 
     1205 
    12001206  // Concat all the names together so they fit into the flat noitd model  
    12011207  concat_metrics(buffer, n->plugin, n->plugin_instance, n->type, n->type_instance); 
    12021208  noit_stats_set_metric(&ccl->current, buffer, METRIC_STRING, n->message); 
    1203   noit_check_set_stats(self, check, &current); 
     1209  noit_check_passive_set_stats(self, check, &current); 
    12041210  noitL(nldeb, "collectd: dispatch_notifications(%s, %s, %s)\n",check->target, buffer, n->message); 
    12051211  return 0; 
     
    12501256    noitL(nldeb, "collectd: queue_values(%s, %s)\n", buffer, check->target); 
    12511257  } 
    1252   //noit_check_set_stats(self, check, &current); 
    12531258  return 0; 
    12541259}  
     
    12641269  collectd_closure_t *ccl; 
    12651270  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 
    12661274  if(!check->closure) { 
    12671275    ccl = check->closure = (void *)calloc(1, sizeof(collectd_closure_t));  
     
    12861294        NP_GOOD : NP_BAD; 
    12871295    ccl->current.status = human_buffer; 
    1288     noit_check_set_stats(self, check, &ccl->current); 
     1296    noit_check_passive_set_stats(self, check, &ccl->current); 
    12891297 
    12901298    memcpy(&check->last_fire_time, &ccl->current.whence, sizeof(duration)); 
     
    12961304static int noit_collectd_handler(eventer_t e, int mask, void *closure, 
    12971305                             struct timeval *now) { 
    1298   struct sockaddr_in  skaddr; 
     1306  union { 
     1307    struct sockaddr_in  skaddr; 
     1308    struct sockaddr_in6 skaddr6; 
     1309  } remote; 
    12991310  char packet[1500]; 
    13001311  int packet_len = sizeof(packet); 
    13011312  unsigned int from_len; 
    1302   char ip_p[INET_ADDRSTRLEN]; 
     1313  char ip_p[INET6_ADDRSTRLEN]; 
    13031314  noit_module_t *self = (noit_module_t *)closure; 
    13041315  collectd_mod_config_t *conf; 
     
    13141325    char *security_buffer;  
    13151326 
    1316     from_len = sizeof(skaddr); 
     1327    from_len = sizeof(remote); 
    13171328 
    13181329    inlen = recvfrom(e->fd, packet, packet_len, 0, 
    1319                      (struct sockaddr *)&skaddr, &from_len); 
     1330                     (struct sockaddr *)&remote, &from_len); 
    13201331    gettimeofday(now, NULL); /* set it, as we care about accuracy */ 
    13211332 
     
    13251336      break; 
    13261337    } 
    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"); 
    13291352      break; 
    13301353    } 
     
    13411364      memset(ccl, 0, sizeof(collectd_closure_t)); 
    13421365    } else { 
    1343       ccl = (collectd_closure_t*)check->closure;  
     1366      ccl = (collectd_closure_t*)check->closure; 
    13441367    } 
    13451368    // Default to NONE 
    1346     ccl->security_level = SECURITY_LEVEL_NONE;      
     1369    ccl->security_level = SECURITY_LEVEL_NONE; 
    13471370    if (noit_hash_retr_str(check->config, "security_level", strlen("security_level"), 
    13481371                           (const char**)&security_buffer))  
     
    14211444  if(!nlerr) nlerr = noit_log_stream_find("error/collectd"); 
    14221445  if(!nldeb) nldeb = noit_log_stream_find("debug/collectd"); 
    1423   if(!nlerr) nlerr = noit_stderr; 
     1446  if(!nlerr) nlerr = noit_error; 
    14241447  if(!nldeb) nldeb = noit_debug; 
    14251448  eventer_name_callback("noit_collectd/handler", noit_collectd_handler); 
     
    14341457  int portint = 0; 
    14351458  struct sockaddr_in skaddr; 
     1459  struct sockaddr_in6 skaddr6; 
     1460  struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; 
    14361461  const char *host; 
    14371462  unsigned short port; 
    14381463 
    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  } 
    14441471  /* Default Collectd port */ 
    1445   portint = 25826
     1472  portint = NET_DEFAULT_PORT
    14461473  if(noit_hash_retr_str(conf->options, 
    14471474                         "collectd_port", strlen("collectd_port"), 
     
    14651492  } 
    14661493  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     */ 
    14831494    if(eventer_set_fd_nonblocking(conf->ipv4_fd)) { 
    14841495      close(conf->ipv4_fd); 
     
    14951506  sockaddr_len = sizeof(skaddr); 
    14961507  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)); 
    14981509    close(conf->ipv4_fd); 
    14991510    return -1; 
     
    15091520    eventer_add(newe); 
    15101521  } 
    1511 /* 
     1522 
    15121523  conf->ipv6_fd = socket(AF_INET6, SOCK_DGRAM, 0); 
    15131524  if(conf->ipv6_fd < 0) { 
    1514     noitL(noit_error, "collectd: socket failed: %s\n", 
     1525    noitL(noit_error, "collectd: IPv6 socket failed: %s\n", 
    15151526          strerror(errno)); 
    15161527  } 
     
    15241535    } 
    15251536  } 
     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 
    15261549  if(conf->ipv6_fd >= 0) { 
    15271550    eventer_t newe; 
     
    15291552    newe->fd = conf->ipv6_fd; 
    15301553    newe->mask = EVENTER_READ; 
    1531     newe->callback = ping_icmp_handler; 
     1554    newe->callback = noit_collectd_handler; 
    15321555    newe->closure = self; 
    15331556    eventer_add(newe); 
    15341557  } 
    1535   */ 
     1558 
    15361559  noit_module_set_userdata(self, conf); 
    15371560  return 0; 
  • src/modules/collectd.xml

    r6c61339 r7d308b7  
    33  <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> 
    44  <loader>C</loader> 
    5   <image>snmp.so</image> 
     5  <image>collectd.so</image> 
    66  <moduleconfig> 
    77    <parameter name="collectd_port" 
     
    99               default="25826" 
    1010               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> 
    1515  </moduleconfig> 
    1616  <checkconfig> 
  • src/noit_check.c

    r6851033 r7d308b7  
    10121012 
    10131013void 
     1014noit_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} 
     1042void 
    10141043noit_check_set_stats(struct _noit_module *module, 
    10151044                     noit_check_t *check, stats_t *newstate) { 
  • src/noit_check.h

    rb553f9a r7d308b7  
    217217 
    218218struct _noit_module; 
     219/* This if for modules (passive) than cannot be watched... */ 
     220API_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... */ 
    219224API_EXPORT(void) 
    220225  noit_check_set_stats(struct _noit_module *self, noit_check_t *check,