Exemplo n.º 1
0
  /**
   * {@inheritDoc}
   *
   * <p>This routine is typically invoked by {@link IGangliaMetricsCollector}s. However, you can
   * also simply invoke it directly.
   *
   * <p>Note: In order to get a nice metadata declaration for the record, the application should
   * also register an {@link IGangliaMetadataFactory}.
   *
   * @param metricName The name of the metric.
   * @param value The metric value.
   * @see #getMetadataFactory()
   */
  @Override
  public void setMetric(final String metricName, final Object value) {

    final GangliaSender sender = this.gangliaSender;

    if (sender != null) {

      try {

        if (metricName == null) {
          log.warn("Metric was emitted with no name.");
          return;
        }

        if (value == null) {
          log.warn("Metric was emitted with a null value: metricName=" + metricName);
          return;
        }

        IGangliaMetadataMessage decl;
        {

          // Look for a pre-declared metric.
          decl = gangliaState.getMetadata(metricName);

          if (decl == null) {

            // Obtain declaration.
            decl = gangliaState.getMetadataFactory().newDecl(hostName, metricName, value);

            if (decl == null) {

              log.error("Could not declare: " + metricName);
              return;
            }

            // Atomically declare/resolve.
            decl = gangliaState.putIfAbsent(decl);
          }
        }

        /*
         * Lookup the current value for the metric.
         *
         * Note: At this point we are guaranteed that a metadata
         * declaration exists so the return value must be non-null.
         */
        final TimestampMetricValue tmv =
            gangliaState.getMetric(getHostName(), decl.getMetricName());

        // Return must be non-null since declaration exists.
        assert tmv != null;

        // Should be the same declaration reference.
        assert decl == tmv.getMetadata();

        if (tmv.getTimestamp() == 0L) {

          /*
           * Send metadata record.
           *
           * TODO Since the captured metadata record might have
           * originated on another host, we should build a new
           * metadata record either now (so we send out the record
           * with our host name) or when we capture the record (as
           * part of obtaining a richer metadata record object).
           */

          sendMessage(tmv.getMetadata());
        }

        // Update the current metric value.
        if (tmv.setValue(value)) {

          /*
           * Send the metric record.
           *
           * Note: Either the metric value has never been transmitted,
           * or it has changed significantly, or TMax might expire if
           * we do not retransmit it now.
           */

          // update the timestamp when sending out the metric value.
          tmv.update();

          final IGangliaMetricMessage msg =
              metricFactory.newMetricMessage(getHostName(), decl, false /* spoof */, value);

          sendMessage(msg);
        }

      } catch (Throwable e) {

        log.warn(e, e);
      }
    }
  }