Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.timgroup.statsd;

import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;

@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5, time = 1)
@Measurement(iterations = 5, time = 1)
@Fork(2)
@State(Scope.Thread)
public class FullPrecisionBenchmark {

@Param({"3.141592653589793", "3.3E20", "42.0", "0.423", "243.5"})
public double value;

private final StringBuilder builder = new StringBuilder(64);

@Benchmark
public int format_default() {
builder.setLength(0);
builder.append(NonBlockingStatsDClient.format(NonBlockingStatsDClient.NUMBER_FORMATTER, value));
return builder.length();
}

@Benchmark
public int format_full_precision() {
builder.setLength(0);
builder.append(value);
return builder.length();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ protected static String format(ThreadLocal<NumberFormat> formatter, Number value
private final String containerID;
private final String externalEnv;
final TagsCardinality clientTagsCardinality;
private final boolean fullPrecision;

/**
* Create a new StatsD client communicating with a StatsD instance on the host and port
Expand All @@ -207,6 +208,7 @@ public NonBlockingStatsDClient(final NonBlockingStatsDClientBuilder builder)
}

blocking = builder.blocking;
fullPrecision = builder.fullPrecision;
maxPacketSizeBytes = builder.maxPacketSizeBytes;
clientTagsCardinality = builder.tagsCardinality;

Expand Down Expand Up @@ -625,7 +627,11 @@ private void send(
tags) {
@Override
protected void writeValue(StringBuilder builder) {
builder.append(format(NUMBER_FORMATTER, this.value));
if (fullPrecision) {
builder.append(this.value);
} else {
builder.append(format(NUMBER_FORMATTER, this.value));
}
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public class NonBlockingStatsDClientBuilder implements Cloneable {

public boolean enableAggregation = NonBlockingStatsDClient.DEFAULT_ENABLE_AGGREGATION;

/** Use full precision when formatting numeric metric values. */
public boolean fullPrecision = true;

/** Telemetry flush interval, in milliseconds. */
public int telemetryFlushInterval = Telemetry.DEFAULT_FLUSH_INTERVAL;

Expand Down Expand Up @@ -270,6 +273,12 @@ public NonBlockingStatsDClientBuilder enableAggregation(boolean val) {
return this;
}

/** Use full precision when formatting numeric metric values. */
public NonBlockingStatsDClientBuilder fullPrecision(boolean val) {
fullPrecision = val;
return this;
}

/** Telemetry flush interval, in milliseconds. */
public NonBlockingStatsDClientBuilder telemetryFlushInterval(int val) {
telemetryFlushInterval = val;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class NonBlockingStatsDClientTest {
private static final int STATSD_SERVER_PORT = 17254;
private NonBlockingStatsDClient client;
private NonBlockingStatsDClient clientUnaggregated;
private NonBlockingStatsDClient clientFullPrecision;
private static UDPDummyStatsDServer server;

private static Logger log = Logger.getLogger("NonBlockingStatsDClientTest");
Expand Down Expand Up @@ -111,8 +112,20 @@ public void start() throws IOException {
.originDetectionEnabled(originDetectionEnabled)
.aggregationFlushInterval(100)
.containerID(containerID)
.fullPrecision(false)
.build();
clientUnaggregated =
new NonBlockingStatsDClientBuilder()
.prefix("my.prefix")
.hostname("localhost")
.port(server.getPort())
.enableTelemetry(false)
.enableAggregation(false)
.originDetectionEnabled(originDetectionEnabled)
.containerID(containerID)
.fullPrecision(false)
.build();
clientFullPrecision =
new NonBlockingStatsDClientBuilder()
.prefix("my.prefix")
.hostname("localhost")
Expand All @@ -128,6 +141,7 @@ public void start() throws IOException {
public void stop() throws IOException {
client.stop();
clientUnaggregated.stop();
clientFullPrecision.stop();
server.close();
}

Expand Down Expand Up @@ -236,6 +250,22 @@ public void sends_double_counter_value_with_incorrect_timestamp() throws Excepti
assertPayload("my.prefix.mycount:42.5|c|T1|#baz,foo:bar");
}

@Test(timeout = 5000L)
public void sends_large_long_counter_to_statsd() throws Exception {
clientUnaggregated.count("mycount", 1L << 62);
server.waitForMessage("my.prefix");

assertPayload("my.prefix.mycount:4611686018427387904|c");
}

@Test(timeout = 5000L)
public void sends_large_long_counter_to_statsd_with_full_precision() throws Exception {
clientFullPrecision.count("mycount", 1L << 62);
server.waitForMessage("my.prefix");

assertPayload("my.prefix.mycount:4611686018427387904|c");
}

@Test(timeout = 5000L)
public void sends_counter_increment_to_statsd() throws Exception {

Expand Down Expand Up @@ -354,10 +384,19 @@ public void sends_gauge_with_sample_rate_to_statsd() throws Exception {
@Test(timeout = 5000L)
public void sends_large_double_gauge_to_statsd() throws Exception {

client.recordGaugeValue("mygauge", 123456789012345.67890);
client.recordGaugeValue("mygauge", 3.3e20);
server.waitForMessage("my.prefix");

assertPayload("my.prefix.mygauge:330000000000000000000|g");
}

@Test(timeout = 5000L)
public void sends_large_double_gauge_to_statsd_with_full_precision() throws Exception {

clientFullPrecision.recordGaugeValue("mygauge", 3.3e20);
server.waitForMessage("my.prefix");

assertPayload("my.prefix.mygauge:123456789012345.67|g");
assertPayload("my.prefix.mygauge:3.3E20|g");
}

@Test(timeout = 5000L)
Expand Down Expand Up @@ -396,6 +435,20 @@ public void sends_gauge_with_sample_rate_to_statsd_with_tags() throws Exception
assertPayload("my.prefix.mygauge:423|g|@1.000000|#baz,foo:bar");
}

@Test(timeout = 5000L)
public void sends_gauge_with_full_precision_to_statsd() throws Exception {
clientFullPrecision.recordGaugeValue("mygauge", Math.PI);
server.waitForMessage("my.prefix");
assertPayload("my.prefix.mygauge:3.141592653589793|g");
}

@Test(timeout = 5000L)
public void sends_gauge_with_full_precision_integer_value_to_statsd() throws Exception {
clientFullPrecision.recordGaugeValue("mygauge", 42.0);
server.waitForMessage("my.prefix");
assertPayload("my.prefix.mygauge:42.0|g");
}

@Test(timeout = 5000L)
public void sends_long_gauge_with_timestamp() throws Exception {
clientUnaggregated.gaugeWithTimestamp("mygauge", 234l, 1205794800, "foo:bar", "baz");
Expand Down