Skip to content

Commit

Permalink
Support sending Graphite metric attributes as tags (#1576)
Browse files Browse the repository at this point in the history
  • Loading branch information
fitzoh committed May 9, 2020
1 parent eeac39b commit d88d9e7
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 8 deletions.
Expand Up @@ -71,6 +71,7 @@ public static class Builder {
private ScheduledExecutorService executor;
private boolean shutdownExecutorOnStop;
private Set<MetricAttribute> disabledMetricAttributes;
private boolean addMetricAttributesAsTags;

private Builder(MetricRegistry registry) {
this.registry = registry;
Expand All @@ -82,6 +83,7 @@ private Builder(MetricRegistry registry) {
this.executor = null;
this.shutdownExecutorOnStop = true;
this.disabledMetricAttributes = Collections.emptySet();
this.addMetricAttributesAsTags = false;
}

/**
Expand Down Expand Up @@ -177,6 +179,24 @@ public Builder disabledMetricAttributes(Set<MetricAttribute> disabledMetricAttri
return this;
}


/**
* Specifies whether or not metric attributes (e.g. "p999", "stddev" or "m15") should be reported in the traditional dot delimited format or in the tag based format.
* Without tags (default): `my.metric.p99`
* With tags: `my.metric;metricattribute=p99`
*
* Note that this setting only modifies the metric attribute, and will not convert any other portion of the metric name to use tags.
* For mor information on Graphite tag support see https://graphite.readthedocs.io/en/latest/tags.html
* See {@link MetricAttribute}.
*
* @param addMetricAttributesAsTags if true, then metric attributes will be added as tags
* @return {@code this}
*/
public Builder addMetricAttributesAsTags(boolean addMetricAttributesAsTags) {
this.addMetricAttributesAsTags = addMetricAttributesAsTags;
return this;
}

/**
* Builds a {@link GraphiteReporter} with the given properties, sending metrics using the
* given {@link GraphiteSender}.
Expand Down Expand Up @@ -207,7 +227,8 @@ public GraphiteReporter build(GraphiteSender graphite) {
filter,
executor,
shutdownExecutorOnStop,
disabledMetricAttributes);
disabledMetricAttributes,
addMetricAttributesAsTags);
}
}

Expand All @@ -216,6 +237,7 @@ public GraphiteReporter build(GraphiteSender graphite) {
private final GraphiteSender graphite;
private final Clock clock;
private final String prefix;
private final boolean addMetricAttributesAsTags;

/**
* Creates a new {@link GraphiteReporter} instance.
Expand All @@ -241,12 +263,14 @@ protected GraphiteReporter(MetricRegistry registry,
MetricFilter filter,
ScheduledExecutorService executor,
boolean shutdownExecutorOnStop,
Set<MetricAttribute> disabledMetricAttributes) {
Set<MetricAttribute> disabledMetricAttributes,
boolean addMetricAttributesAsTags) {
super(registry, "graphite-reporter", filter, rateUnit, durationUnit, executor, shutdownExecutorOnStop,
disabledMetricAttributes);
this.graphite = graphite;
this.clock = clock;
this.prefix = prefix;
this.addMetricAttributesAsTags = addMetricAttributesAsTags;
}

@Override
Expand Down Expand Up @@ -348,18 +372,18 @@ private void sendIfEnabled(MetricAttribute type, String name, double value, long
if (getDisabledMetricAttributes().contains(type)) {
return;
}
graphite.send(prefix(name, type.getCode()), format(value), timestamp);
graphite.send(prefix(appendMetricAttribute(name, type.getCode())), format(value), timestamp);
}

private void sendIfEnabled(MetricAttribute type, String name, long value, long timestamp) throws IOException {
if (getDisabledMetricAttributes().contains(type)) {
return;
}
graphite.send(prefix(name, type.getCode()), format(value), timestamp);
graphite.send(prefix(appendMetricAttribute(name, type.getCode())), format(value), timestamp);
}

private void reportCounter(String name, Counter counter, long timestamp) throws IOException {
graphite.send(prefix(name, COUNT.getCode()), format(counter.getCount()), timestamp);
graphite.send(prefix(appendMetricAttribute(name, COUNT.getCode())), format(counter.getCount()), timestamp);
}

private void reportGauge(String name, Gauge<?> gauge, long timestamp) throws IOException {
Expand Down Expand Up @@ -390,8 +414,15 @@ private String format(Object o) {
return null;
}

private String prefix(String... components) {
return MetricRegistry.name(prefix, components);
private String prefix(String name) {
return MetricRegistry.name(prefix, name);
}

private String appendMetricAttribute(String name, String metricAttribute){
if (addMetricAttributesAsTags){
return name + ";metricattribute=" + metricAttribute;
}
return name + "." + metricAttribute;
}

private String format(long n) {
Expand Down
Expand Up @@ -464,17 +464,50 @@ public void disabledMetricsAttribute() throws Exception {
verifyNoMoreInteractions(graphite);
}

@Test
public void sendsMetricAttributesAsTagsIfEnabled() throws Exception {
final Counter counter = mock(Counter.class);
when(counter.getCount()).thenReturn(100L);

getReporterThatSendsMetricAttributesAsTags().report(map(),
map("counter", counter),
map(),
map(),
map());

final InOrder inOrder = inOrder(graphite);
inOrder.verify(graphite).connect();
inOrder.verify(graphite).send("prefix.counter;metricattribute=count", "100", timestamp);
inOrder.verify(graphite).flush();
inOrder.verify(graphite).close();

verifyNoMoreInteractions(graphite);
}

private GraphiteReporter getReporterWithCustomFormat() {
return new GraphiteReporter(registry, graphite, clock, "prefix",
TimeUnit.SECONDS, TimeUnit.MICROSECONDS, MetricFilter.ALL, null, false,
Collections.emptySet()) {
Collections.emptySet(), false) {
@Override
protected String format(double v) {
return String.format(Locale.US, "%4.4f", v);
}
};
}


private GraphiteReporter getReporterThatSendsMetricAttributesAsTags() {
return GraphiteReporter.forRegistry(registry)
.withClock(clock)
.prefixedWith("prefix")
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.filter(MetricFilter.ALL)
.disabledMetricAttributes(Collections.emptySet())
.addMetricAttributesAsTags(true)
.build(graphite);
}

private <T> SortedMap<String, T> map() {
return new TreeMap<>();
}
Expand Down

0 comments on commit d88d9e7

Please sign in to comment.