Exemplo n.º 1
0
    @Override
    public void accept(final IGangliaMessage msg) {

      if (msg == null) return;

      /*
       * true iff the message is from this host.
       *
       * Note: A message from this host could be from either an embedded
       * ganglia service (such as ourselves) or from gmond or even gmetad
       * (if we are running on the same host as gmetad).
       *
       * It is Ok to accept metric value updates from ourselves, and this
       * makes it possible to listen to a gmond instance on the same host.
       * However, the receipt of a metric value MUST NOT cause us to send
       * out a new metric value record.
       */

      if (msg.isMetricRequest()) {

        /*
         * Metadata request.
         */
        if (isQuietPeriod()) {
          /*
           * Ignore requests during the quiet period.
           *
           * TODO Review the quite period behavior.  Is this correct?
           */
          return;
        }

        /*
         * Lookup the metric value for *this* host.
         */
        final TimestampMetricValue tmv = gangliaState.getMetric(hostName, msg.getMetricName());

        if (tmv != null && tmv.getTimestamp() != 0L) {

          /*
           * If the requested metric is known on this host then we
           * reset it now. The next time we sample that metric it will
           * have a timestamp of ZERO (0) and will be sent out to all
           * listeners. Since the timestamp is ZERO (0) (rather than a
           * valid timestamp at which the metric was last sent), the
           * metadata record will also be sent out.
           */

          tmv.resetTimestamp();

          if (log.isInfoEnabled()) log.info("Reset metric timestamp: " + msg.toString());
        }

      } else if (msg.isMetricMetadata()) {

        /*
         * Handle metadata message.
         *
         * TODO Allow a pattern for metrics that we will accept. Do not
         * store the declaration unless it satisfies that pattern.
         */

        if (gangliaState.putIfAbsent((IGangliaMetadataMessage) msg) == null) {

          if (log.isInfoEnabled()) log.info("declared by host: " + msg.toString());
        }

      } else if (msg.isMetricValue()) {

        /*
         * TODO Allow a pattern for metrics that we will accept. Do not
         * store the declaration unless it satisfies that pattern.
         */

        if (gangliaState.getMetadata(msg.getMetricName()) == null) {

          /*
           * Request the metadata for the metric.
           *
           * Note: We will not accept the metric record into our
           * internal state until we have received a metadata record
           * for that metric.
           */

          if (log.isDebugEnabled()) log.debug("No metadata for metric: " + msg.getMetricName());

          sendMessage(new GangliaRequestMessage(hostName, msg.getMetricName(), false /* spoof */));

          return;
        }

        /*
         * Update the counters for the appropriate host.
         *
         * Note: At this point we have verified that we have a metadata
         * declaration on hand for this metric so we can go ahead and
         * store the metric value in our internal state.
         */

        final IGangliaMetricMessage m2 = (IGangliaMetricMessage) msg;

        final TimestampMetricValue tmv =
            gangliaState.getMetric(msg.getHostName(), msg.getMetricName());

        // Guaranteed non-null since metadata decl exists for metric.
        assert tmv != null;

        /*
         * Update the value.
         *
         * Note: The return value is ignored. Since the metric was
         * received over the wire we ignore the age of the metric rather
         * than using the metric age to trigger a send of the metric
         * value. (I.e., avoid re-sending received metrics.)
         */
        tmv.setValue(m2.getValue());

        if (log.isDebugEnabled()) log.debug("Updated value: " + msg);

      } else {

        log.error("Unknown message type: " + msg);
      }
    }