com.signalfx.codahale.reporter.SignalFxReporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of signalfx-codahale Show documentation
Show all versions of signalfx-codahale Show documentation
Dropwizard Codahale metrics plugin for signalfx
The newest version!
/**
* Copyright (C) 2015 SignalFx, Inc.
*/
package com.signalfx.codahale.reporter;
import static java.util.Objects.requireNonNull;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.ScheduledReporter;
import com.codahale.metrics.Timer;
import com.signalfx.shaded.google.common.collect.ImmutableMap;
import com.signalfx.shaded.google.common.collect.ImmutableSet;
import com.signalfx.endpoint.SignalFxEndpoint;
import com.signalfx.endpoint.SignalFxReceiverEndpoint;
import com.signalfx.metrics.SourceNameHelper;
import com.signalfx.metrics.auth.AuthToken;
import com.signalfx.metrics.auth.StaticAuthToken;
import com.signalfx.metrics.connection.DataPointReceiverFactory;
import com.signalfx.metrics.connection.HttpDataPointProtobufReceiverFactory;
import com.signalfx.metrics.errorhandler.OnSendErrorHandler;
import com.signalfx.metrics.flush.AggregateMetricSender;
import com.signalfx.metrics.protobuf.SignalFxProtocolBuffers;
/**
* Reporter object for codahale metrics that reports values to com.signalfx.signalfx at some
* interval.
* @deprecated Migrate to OpenTelemetry to send metric telemetry to Splunk.
*/
@Deprecated
public class SignalFxReporter extends ScheduledReporter {
private final AggregateMetricSender aggregateMetricSender;
private final Set detailsToAdd;
private final MetricMetadata metricMetadata;
private final boolean useLocalTime;
private final ImmutableMap defaultDimensions;
protected SignalFxReporter(MetricRegistry registry, String name, MetricFilter filter,
TimeUnit rateUnit, TimeUnit durationUnit,
AggregateMetricSender aggregateMetricSender,
Set detailsToAdd,
MetricMetadata metricMetadata) {
this(registry, name, filter, rateUnit, durationUnit, aggregateMetricSender, detailsToAdd,
metricMetadata, false, Collections. emptyMap());
}
public SignalFxReporter(MetricRegistry registry, String name, MetricFilter filter,
TimeUnit rateUnit, TimeUnit durationUnit,
AggregateMetricSender aggregateMetricSender,
Set detailsToAdd, MetricMetadata metricMetadata,
boolean useLocalTime, Map defaultDimensions) {
super(registry, name, filter, rateUnit, durationUnit);
this.aggregateMetricSender = aggregateMetricSender;
this.useLocalTime = useLocalTime;
this.detailsToAdd = detailsToAdd;
this.metricMetadata = metricMetadata;
this.defaultDimensions = ImmutableMap.copyOf(defaultDimensions);
}
@Override
public void report(SortedMap gauges, SortedMap counters,
SortedMap histograms, SortedMap meters,
SortedMap timers) {
AggregateMetricSenderSessionWrapper session = new AggregateMetricSenderSessionWrapper(
aggregateMetricSender.createSession(), Collections.unmodifiableSet(detailsToAdd), metricMetadata,
aggregateMetricSender.getDefaultSourceName(), "sf_source", useLocalTime, defaultDimensions);
try {
for (Map.Entry entry : gauges.entrySet()) {
session.addMetric(entry.getValue(), entry.getKey(),
SignalFxProtocolBuffers.MetricType.GAUGE, entry.getValue().getValue());
}
for (Map.Entry entry : counters.entrySet()) {
if (entry.getValue() instanceof IncrementalCounter) {
session.addMetric(entry.getValue(), entry.getKey(),
SignalFxProtocolBuffers.MetricType.COUNTER,
((IncrementalCounter)entry.getValue()).getCountChange());
} else {
session.addMetric(entry.getValue(), entry.getKey(),
SignalFxProtocolBuffers.MetricType.CUMULATIVE_COUNTER,
entry.getValue().getCount());
}
}
for (Map.Entry entry : histograms.entrySet()) {
session.addHistogram(entry.getKey(), entry.getValue());
}
for (Map.Entry entry : meters.entrySet()) {
session.addMetered(entry.getKey(), entry.getValue());
}
for (Map.Entry entry : timers.entrySet()) {
session.addTimer(entry.getKey(), entry.getValue());
}
} finally {
try {
session.close();
} catch (Exception e) {
// Unable to register... these exceptions handled by AggregateMetricSender
}
}
}
public MetricMetadata getMetricMetadata() {
return metricMetadata;
}
public enum MetricDetails {
// For {@link com.codahale.metrics.Sampling}
MEDIAN("median"),
PERCENT_75("75th"),
PERCENT_95("95th"),
PERCENT_98("98th"),
PERCENT_99("99th"),
PERCENT_999("999th"),
MAX("max"),
MIN("min"),
STD_DEV("stddev"),
MEAN("mean"),
// For {@link com.codahale.metrics.Counting}
COUNT("count"),
// For {@link com.codahale.metrics.Metered}
RATE_MEAN("rate.mean"),
RATE_1_MIN("rate.1min"),
RATE_5_MIN("rate.5min"),
RATE_15_MIN("rate.15min");
public static final Set ALL = Collections.unmodifiableSet(EnumSet.allOf(MetricDetails.class));
public static final Set DEFAULTS = ImmutableSet.of(COUNT, MIN, MEAN, MAX);
private final String description;
MetricDetails(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
public static final class Builder {
private final MetricRegistry registry;
private String defaultSourceName;
private AuthToken authToken;
private SignalFxReceiverEndpoint endpoint = new SignalFxEndpoint();
private String name = "signalfx-reporter";
private int timeoutMs = HttpDataPointProtobufReceiverFactory.DEFAULT_TIMEOUT_MS;
private DataPointReceiverFactory dataPointReceiverFactory = new
HttpDataPointProtobufReceiverFactory(endpoint);
private MetricFilter filter = MetricFilter.ALL;
private TimeUnit rateUnit = TimeUnit.SECONDS;
private TimeUnit durationUnit = TimeUnit.MILLISECONDS; // Maybe nano eventually?
private Set detailsToAdd = MetricDetails.DEFAULTS;
private Collection onSendErrorHandlerCollection = Collections.emptyList();
private MetricMetadata metricMetadata = new MetricMetadataImpl();
private boolean useLocalTime = false;
private final ImmutableMap.Builder defaultDimensions = new ImmutableMap.Builder();
public Builder(MetricRegistry registry, String authToken) {
this(registry, new StaticAuthToken(authToken));
}
public Builder(MetricRegistry registry, AuthToken authToken) {
this(registry, authToken, SourceNameHelper.getDefaultSourceName());
}
public Builder(MetricRegistry registry, AuthToken authToken, String defaultSourceName) {
this.registry = registry;
this.authToken = authToken;
this.defaultSourceName = requireNonNull(defaultSourceName, "defaultSourceName must be a non-null value");
}
public Builder setDefaultSourceName(String defaultSourceName) {
this.defaultSourceName = requireNonNull(defaultSourceName, "defaultSourceName must be a non-null value");
return this;
}
public Builder setAuthToken(AuthToken authToken) {
this.authToken = authToken;
return this;
}
public Builder setEndpoint(SignalFxReceiverEndpoint endpoint) {
this.endpoint = endpoint;
this.dataPointReceiverFactory =
new HttpDataPointProtobufReceiverFactory(endpoint)
.setTimeoutMs(this.timeoutMs);
return this;
}
public Builder setName(String name) {
this.name = name;
return this;
}
public Builder setTimeoutMs(int timeoutMs) {
this.timeoutMs = timeoutMs;
this.dataPointReceiverFactory =
new HttpDataPointProtobufReceiverFactory(endpoint)
.setTimeoutMs(this.timeoutMs);
return this;
}
@Deprecated
public Builder setVersion(int version) {
return this;
}
public Builder setDataPointReceiverFactory(
DataPointReceiverFactory dataPointReceiverFactory) {
this.dataPointReceiverFactory = dataPointReceiverFactory;
return this;
}
public Builder setFilter(MetricFilter filter) {
this.filter = filter;
return this;
}
public Builder setRateUnit(TimeUnit rateUnit) {
this.rateUnit = rateUnit;
return this;
}
public Builder setDurationUnit(TimeUnit durationUnit) {
this.durationUnit = durationUnit;
return this;
}
public Builder setDetailsToAdd(Set detailsToAdd) {
this.detailsToAdd = detailsToAdd;
return this;
}
public Builder setOnSendErrorHandlerCollection(
Collection onSendErrorHandlerCollection) {
this.onSendErrorHandlerCollection = onSendErrorHandlerCollection;
return this;
}
public Builder setMetricMetadata(MetricMetadata metricMetadata) {
this.metricMetadata = metricMetadata;
return this;
}
/**
* Will use the local system time, rather than zero, on sent datapoints.
* @param useLocalTime If true, use local system time
* @return this
*/
public Builder useLocalTime(boolean useLocalTime) {
this.useLocalTime = useLocalTime;
return this;
}
/**
* Adds all dimensions to the default dimensions to be sent with every datapoint from this
* reporter. This means they will be added to distributed counters (as opposed to cumulative counters),
* which means that if there is any dimension in this map which is unique to the emitter (i.e a hostname)
* then the distributed counter will not aggregate as expected. For dimension that are unique to each emitter use
* either {@link #addUniqueDimension(String, String)} or {@link #addUniqueDimensions(Map)}
*
* @param dimensions
* non-null map of string value pairs
* @return this
*/
public Builder addDimensions(Map dimensions) {
// loop here to get "null value" protection of addDimension
for (Map.Entry entry: dimensions.entrySet()) {
this.addDimension(entry.getKey(), entry.getValue());
}
return this;
}
/**
* Adds a dimension to the default dimensions to be sent with every datapoint from this
* reporter. This means they will be added to distributed counters (as opposed to cumulative counters),
* which means that if the name and value is unique to the emitter (i.e a hostname)
* then the distributed counter will not aggregate as expected. For dimension that are unique to each emitter use
* {@link #addUniqueDimension(String, String)}
*
* @param name
* Name of the dimension
* @param value
* Value of the dimension. If null then the dimension is not added.
* @return this
*/
public Builder addDimension(String name, String value) {
if (value != null) {
this.defaultDimensions.put(name, DimensionInclusion.shared(value));
}
return this;
}
/**
* Adds all dimensions to the default dimensions to be sent with every datapoint that is not a distributed counter.
* This method should be used for adding dimensions which are unique to the emitter (such as host name), for shared
* dimensions which can be sent with distributed counters use either {@link #addDimension(String, String)} or {@link #addDimensions(Map)}
* @param dimensions
* non-null map of string value pairs
* @return this
*/
public Builder addUniqueDimensions(Map dimensions) {
// loop here to get "null value" protection of addDimension
for (Map.Entry entry: dimensions.entrySet()) {
this.addUniqueDimension(entry.getKey(), entry.getValue());
}
return this;
}
/**
* Adds a dimension to the default dimensions to be sent with every datapoint that is not a distributed counter.
* This method should be used for adding dimensions which are unique to the emitter (such as host name), for shared
* dimensions use {@link #addDimension(String, String)}
*
* @param name
* Name of the dimension
* @param value
* Value of the dimension. If null then the dimension is not added.
* @return this
*/
public Builder addUniqueDimension(String name, String value) {
if (value != null) {
this.defaultDimensions.put(name, DimensionInclusion.unique(value));
}
return this;
}
public SignalFxReporter build() {
AggregateMetricSender aggregateMetricSender = new AggregateMetricSender(
defaultSourceName, dataPointReceiverFactory, authToken,
onSendErrorHandlerCollection);
return new SignalFxReporter(registry, name, filter, rateUnit, durationUnit,
aggregateMetricSender, detailsToAdd, metricMetadata, useLocalTime,
defaultDimensions.build());
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy