/** * Return the factory for metric declarations. If you supply a {@link GangliaMetadataFactory} * instance to the constructor (which is the default behavior for the reduced constructor) then * you can extend the default behavior in order to get nice metadata declarations for your * application metrics. */ public IGangliaMetadataFactory getMetadataFactory() { return gangliaState.getMetadataFactory(); }
/** * {@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); } } }