コード例 #1
0
ファイル: server.c プロジェクト: tstarling/monitor-core
xml_print( client_t *client, const char *fmt, ... )
{
    int rval, len;
    va_list ap;
    char buf[4096];

    va_start (ap, fmt);

    if(! client->valid )
    {
        va_end(ap);
        return 1;
    }

    vsnprintf (buf, sizeof (buf), fmt, ap);

    len = strlen(buf);

    SYS_CALL( rval, write( client->fd, buf, len));
    if ( rval < 0 && rval != len )
    {
        va_end(ap);
        client->valid = 0;
        return 1;
    }

    va_end(ap);
    return 0;
}
コード例 #2
0
ファイル: server.c プロジェクト: tstarling/monitor-core
void *
server_thread (void *arg)
{
    int interactive = (arg != NULL);
    socklen_t len;
    int request_len;
    client_t client;
    char remote_ip[16];
    char request[REQUESTLEN + 1];
    llist_entry *le;
    datum_t rootdatum;

    for (;;)
    {
        client.valid = 0;
        len = sizeof(client.addr);

        if (interactive)
        {
            pthread_mutex_lock(&server_interactive_mutex);
            SYS_CALL( client.fd, accept(interactive_socket->sockfd, (struct sockaddr *) &(client.addr), &len));
            pthread_mutex_unlock(&server_interactive_mutex);
        }
        else
        {
            pthread_mutex_lock  ( &server_socket_mutex );
            SYS_CALL( client.fd, accept(server_socket->sockfd, (struct sockaddr *) &(client.addr), &len));
            pthread_mutex_unlock( &server_socket_mutex );
        }
        if ( client.fd < 0 )
        {
            err_ret("server_thread() error");
            debug_msg("server_thread() %lx clientfd = %d errno=%d\n",
                      (unsigned long) pthread_self(), client.fd, errno);
            continue;
        }

        my_inet_ntop( AF_INET, (void *)&(client.addr.sin_addr), remote_ip, 16 );

        if ( !strcmp(remote_ip, "127.0.0.1")
                || gmetad_config.all_trusted
                || (llist_search(&(gmetad_config.trusted_hosts), (void *)remote_ip, strcmp, &le) == 0) )
        {
            client.valid = 1;
        }

        if(! client.valid )
        {
            debug_msg("server_thread() %s tried to connect and is not a trusted host",
                      remote_ip);
            close( client.fd );
            continue;
        }

        client.filter=0;
        client.http=0;
        gettimeofday(&client.now, NULL);

        if (interactive)
        {
            request_len = readline(client.fd, request, REQUESTLEN);
            if (request_len < 0)
            {
                err_msg("server_thread() could not read request from %s", remote_ip);
                close(client.fd);
                continue;
            }
            debug_msg("server_thread() received request \"%s\" from %s", request, remote_ip);

            if (process_request(&client, request))
            {
                err_msg("Got a malformed path request from %s", remote_ip);
                close(client.fd);
                continue;
            }
        }
        else
            strcpy(request, "/");

        if(root_report_start(&client))
        {
            err_msg("server_thread() %lx unable to write root preamble (DTD, etc)",
                    (unsigned long) pthread_self() );
            close(client.fd);
            continue;
        }

        /* Start search at the root node. */
        rootdatum.data = &root;
        rootdatum.size = sizeof(root);

        if (process_path(&client, request, &rootdatum, NULL))
        {
            err_msg("server_thread() %lx unable to write XML tree info",
                    (unsigned long) pthread_self() );
            close(client.fd);
            continue;
        }

        if(root_report_end(&client))
        {
            err_msg("server_thread() %lx unable to write root epilog",
                    (unsigned long) pthread_self() );
        }

        close(client.fd);
    }
}
コード例 #3
0
ファイル: server.c プロジェクト: olahaye74/monitor-core
static int
status_report( client_t *client )
{
   int rval, len;
   char buf[4096];

   debug_msg("Stat request...");

   if(! client->valid )
      {
         return 1;
      }

   apr_time_t now = apr_time_now();

   snprintf (buf, sizeof (buf),
       "HTTP/1.0 200 OK\r\n"
       "Server: gmetad/" GANGLIA_VERSION_FULL "\r\n"
       "Content-Type: application/json\r\n"
       "Connection: close\r\n"
       "\r\n"
       "{"
       "\"host\":\"%s\","
       "\"gridname\":\"%s\","
       "\"version\":\"%s\","
       "\"boottime\":%lu,"
       "\"uptime\":%lu,"
       "\"uptimeMillis\":%lu,"
       "\"metrics\":{"
       "\"received\":{"
       "\"all\":%d"
       "},"
       "\"sent\":{"
       "\"all\":%d,"
       "\"rrdtool\":%d,"
       "\"rrdcached\":%d,"
       "\"graphite\":%d,"
       "\"memcached\":%d,"
       "\"riemann\":%d"
       "}}"
       "}\r\n",
       hostname,
       gmetad_config.gridname,
       GANGLIA_VERSION_FULL,
       (long int)(started / APR_TIME_C(1000)), // ms
       (long int)((now - started) / APR_USEC_PER_SEC), // ms
       (long int)((now - started) / APR_TIME_C(1000)), // ms
       ganglia_scoreboard_get("gmetad_metrics_recvd_all"),
       ganglia_scoreboard_get("gmetad_metrics_sent_all"),
       ganglia_scoreboard_get("gmetad_metrics_sent_rrdtool"),
       ganglia_scoreboard_get("gmetad_metrics_sent_rrdcached"),
       ganglia_scoreboard_get("gmetad_metrics_sent_graphite"),
       ganglia_scoreboard_get("gmetad_metrics_sent_memcached"),
       ganglia_scoreboard_get("gmetad_metrics_sent_riemann")
   );

   void *sbi = ganglia_scoreboard_iterator();
   while (sbi) {
      char *name = ganglia_scoreboard_next(&sbi);
      int val = ganglia_scoreboard_get(name);
      debug_msg("%s = %d", name, val);
   }

   len = strlen(buf);

   SYS_CALL( rval, write( client->fd, buf, len));
   if ( rval < 0 && rval != len )
      {
         client->valid = 0;
         return 1;
      }

   return 0;
}
コード例 #4
0
void *
data_thread ( void *arg )
{
   int i, bytes_read, rval;
   data_source_list_t *d = (data_source_list_t *)arg;
   g_inet_addr *addr;
   g_tcp_socket *sock=0;
   datum_t key;
   char *buf;
   /* This will grow as needed */
   unsigned int buf_size = 1024, read_index;
   struct pollfd struct_poll;
   apr_time_t start, end;
   apr_interval_time_t sleep_time, elapsed;
   double random_factor;
   unsigned int rand_seed;

   rand_seed = apr_time_now() * (int)pthread_self();
   for(i = 0; d->name[i] != 0; rand_seed = rand_seed * d->name[i++]);
 
   if(get_debug_msg_level())
      {
         fprintf(stderr,"Data thread %lu is monitoring [%s] data source\n", (unsigned long)pthread_self(), d->name);
         for(i = 0; i < d->num_sources; i++)
            {
               addr = d->sources[i];
               fprintf(stderr, "\t%s\n", addr->name);
            }
      }

   key.data = d->name;
   key.size = strlen( key.data ) + 1;

   buf = malloc( buf_size );
   if(!buf)
      {
         err_quit("data_thread() unable to malloc initial buffer for [%s] data source\n", d->name);
      }

   /* Assume the best from the beginning */
   d->dead = 0;

   for (;;)
      {
         start = apr_time_now();
         sock = NULL;
         
         /* If we successfully read from a good data source last time then try the same host again first. */
         if(d->last_good_index != -1)
           sock = g_tcp_socket_new ( d->sources[d->last_good_index] );

         /* If there was no good connection last time or the above connect failed then try each host in the list. */
         if(!sock)
           {
             for(i=0; i < d->num_sources; i++)
               {
                 /* Find first viable source in list. */
                 sock = g_tcp_socket_new ( d->sources[i] );
                 if( sock )
                   {
                     d->last_good_index = i;
                     break;
                   }
                 else
                   {
                     err_msg("data_thread() for [%s] failed to contact node %s", d->name, d->sources[i]->name);
                   }
               }
           }

         if(!sock)
            {
               err_msg("data_thread() got no answer from any [%s] datasource", d->name);
               d->dead = 1;
               goto take_a_break;
            }

         struct_poll.fd = sock->sockfd;
         struct_poll.events = POLLIN; 

         read_index = 0;
         for(;;)
            {
               /* Timeout set to 10 seconds */
               rval = poll( &struct_poll, 1, 10000);
               if( rval < 0 )
                  {
                     /* Error */
                     err_msg("poll() error in data_thread from source %d for [%s] data source after %d bytes read", d->last_good_index, d->name, read_index);
                     if (d->last_good_index < (d->num_sources - 1))
                        d->last_good_index += 1; /* skip this source */
                     else
                        d->last_good_index = -1; /* forget this source */
                     d->dead = 1;
                     goto take_a_break;
                  }
               else if (rval == 0)
                  {
                     /* No revents during timeout period */
                     err_msg("poll() timeout from source %d for [%s] data source after %d bytes read", d->last_good_index, d->name, read_index);
                     if (d->last_good_index < (d->num_sources - 1))
                        d->last_good_index += 1; /* skip this source */
                     else
                        d->last_good_index = -1; /* forget this source */
                     d->dead = 1;
                     goto take_a_break; 
                  }
               else
                  {
                     if( struct_poll.revents & POLLIN )
                        {
                           if( (read_index + 1024) > buf_size )
                              {
                                 /* We need to malloc more space for the data */
                                 buf = realloc( buf, buf_size+1024 );
                                 if(!buf)
                                    {
                                       err_quit("data_thread() unable to malloc enough room for [%s] XML", d->name);
                                    }
                                 buf_size+=1024;
                              }
                           SYS_CALL( bytes_read, read(sock->sockfd, buf+read_index, 1023));
                           if (bytes_read < 0)
                              {
                                 err_msg("data_thread() unable to read() socket for [%s] data source", d->name);
                                 d->last_good_index = -1;
                                 d->dead = 1;
                                 goto take_a_break;
                              }
                           else if(bytes_read == 0)
                              {
                                 break;
                              }
                           read_index+= bytes_read;
                        }
                        /* Appears that OSX uses POLLHUP on Sockets that I have loaded the entire message into the buffer...
                         * not that I lost the connection (See FreeBSD lists on this discussion)
                         */
#if !(defined(DARWIN))
                     if( struct_poll.revents & POLLHUP )
                        {
                           err_msg("The remote machine closed connection for [%s] data source after %d bytes read", d->name, read_index);
                           d->last_good_index = -1;
                           d->dead = 1;
                           goto take_a_break;
                        }
#endif /* DARWIN */
                     if( struct_poll.revents & POLLERR )
                        {
                           err_msg("POLLERR! for [%s] data source after %d bytes read", d->name, read_index);
                           d->last_good_index = -1;
                           d->dead = 1;
                           goto take_a_break;
                        }
                     if( struct_poll.revents & POLLNVAL )
                        {
                           err_msg("POLLNVAL! for [%s] data source after %d bytes read", d->name, read_index);
                           d->last_good_index = -1;
                           d->dead = 1;
                           goto take_a_break;
                        }
                  }
            }

         buf[read_index] = '\0';

         /* Parse the buffer */
         rval = process_xml(d, buf);
         if(rval)
            {
               /* We no longer consider the source dead if its XML parsing
                * had an error - there may be other reasons for this (rrd issues, etc). 
                */
               goto take_a_break;
            }

         /* We processed all the data.  Mark this source as alive */
         d->dead = 0;

       take_a_break:
         g_tcp_socket_delete(sock);

         end = apr_time_now();
         /* Sleep somewhere between (step +/- SLEEP_RANDOMIZE percent.) */
         random_factor = 1 + (SLEEP_RANDOMIZE / 50.0) * ((rand_r(&rand_seed) - RAND_MAX/2)/(float)RAND_MAX);
         elapsed = end - start;
         sleep_time = apr_time_from_sec(d->step) * random_factor - elapsed;
         if(sleep_time > 0)
           apr_sleep(sleep_time); 
      }
   return NULL;
}