diff --git a/src/main/java/com/timgroup/statsd/NonBlockingStatsDClient.java b/src/main/java/com/timgroup/statsd/NonBlockingStatsDClient.java index 3b4661b7..10a8825f 100644 --- a/src/main/java/com/timgroup/statsd/NonBlockingStatsDClient.java +++ b/src/main/java/com/timgroup/statsd/NonBlockingStatsDClient.java @@ -11,7 +11,8 @@ import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.concurrent.BlockingQueue; @@ -53,9 +54,29 @@ */ public class NonBlockingStatsDClient implements StatsDClient { - public static final String DD_DOGSTATSD_PORT_ENV_VAR = "DD_DOGSTATSD_PORT"; - public static final String DD_AGENT_HOST_ENV_VAR = "DD_AGENT_HOST"; - public static final String DD_ENTITY_ID_ENV_VAR = "DD_ENTITY_ID"; + static final String DD_DOGSTATSD_PORT_ENV_VAR = "DD_DOGSTATSD_PORT"; + static final String DD_AGENT_HOST_ENV_VAR = "DD_AGENT_HOST"; + static final String DD_ENTITY_ID_ENV_VAR = "DD_ENTITY_ID"; + private static final String ENTITY_ID_TAG_NAME = "dd.internal.entity_id" ; + + enum Literal { + service, + env, + version, + tags; + private static final String PREFIX = "dd"; + String envName() { + return (PREFIX + "_" + toString()).toUpperCase(); + } + + String envVal() { + return System.getenv(envName()); + } + + String tag() { + return PREFIX + "." + toString(); + } + } public static final int DEFAULT_MAX_PACKET_SIZE_BYTES = 1400; public static final int DEFAULT_QUEUE_SIZE = 4096; @@ -140,8 +161,6 @@ protected NumberFormat initialValue() { protected final StatsDSender statsDSender; protected final Telemetry telemetry; - private final String ENTITY_ID_TAG_NAME = "dd.internal.entity_id" ; - /** * Create a new StatsD client communicating with a StatsD instance on the * specified host and port. All messages send via this client will have @@ -202,17 +221,27 @@ public NonBlockingStatsDClient(final String prefix, final int queueSize, String[ handler = errorHandler; } - /* Empty list should be null for faster comparison */ - if ((constantTags != null) && (constantTags.length == 0)) { - constantTags = null; - } - - // Support "dd.internal.entity_id" internal tag. - constantTags = this.updateTagsWithEntityID(constantTags, entityID); - if (constantTags != null) { - constantTagsRendered = tagString(constantTags, null); - } else { - constantTagsRendered = null; + { + List costantPreTags = new ArrayList<>(); + if (constantTags != null) { + for (final String constantTag : constantTags) { + costantPreTags.add(constantTag); + } + } + // Support "dd.internal.entity_id" internal tag. + updateTagsWithEntityID(costantPreTags, entityID); + for (final Literal literal : Literal.values()) { + final String envVal = literal.envVal(); + if (envVal != null && !envVal.trim().isEmpty()) { + costantPreTags.add(literal.tag() + ":" + envVal); + } + } + if (costantPreTags.isEmpty()) { + constantTagsRendered = null; + } else { + constantTagsRendered = tagString(costantPreTags.toArray(new String[costantPreTags.size()]), null); + } + costantPreTags = null; } String transportType = ""; @@ -1008,33 +1037,23 @@ public void recordServiceCheckRun(final ServiceCheck sc) { /** * Updates and returns tags completed with the entityID tag if needed. * - * @param tags the current constant tags array + * @param tags the current constant tags list * * @param entityID the entityID string provided by argument * - * @return array of tags + * @return true if tags was modified */ - private String[] updateTagsWithEntityID(String[] tags, String entityID) { + private static boolean updateTagsWithEntityID(final List tags, String entityID) { // Support "dd.internal.entity_id" internal tag. if (entityID == null || entityID.trim().isEmpty()) { // if the entityID parameter is null, default to the environment variable entityID = System.getenv(DD_ENTITY_ID_ENV_VAR); } if (entityID != null && !entityID.trim().isEmpty()) { - final String entityTag = new StringBuilder(ENTITY_ID_TAG_NAME) - .append(":") - .append(entityID) - .toString(); - - if (tags == null) { - tags = new String[]{entityTag}; - } else { - tags = Arrays.copyOf(tags, tags.length + 1); - // Now that tags is one element longer, tags.length has changed... - tags[tags.length - 1] = entityTag; - } + final String entityTag = ENTITY_ID_TAG_NAME + ":" + entityID; + return tags.add(entityTag); } - return tags; + return false; } private String toStatsDString(final ServiceCheck sc) { diff --git a/src/test/java/com/timgroup/statsd/NonBlockingStatsDClientTest.java b/src/test/java/com/timgroup/statsd/NonBlockingStatsDClientTest.java index feedef81..9d833c08 100644 --- a/src/test/java/com/timgroup/statsd/NonBlockingStatsDClientTest.java +++ b/src/test/java/com/timgroup/statsd/NonBlockingStatsDClientTest.java @@ -5,24 +5,23 @@ import org.junit.BeforeClass; import org.junit.Test; import org.junit.Rule; +import org.junit.contrib.java.lang.system.EnvironmentVariables; import java.io.IOException; import java.net.SocketAddress; -import java.nio.ByteBuffer; -import java.nio.channels.DatagramChannel; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Locale; -import java.util.logging.Logger; -import java.util.concurrent.BlockingQueue; +import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.junit.contrib.java.lang.system.EnvironmentVariables; public class NonBlockingStatsDClientTest { @@ -45,12 +44,11 @@ public static void start() throws IOException { } @AfterClass - public static void stop() throws Exception { + public static void stop() { try { client.stop(); server.close(); - } catch (java.io.IOException e) { - return; + } catch (java.io.IOException ignored) { } } @@ -129,7 +127,7 @@ public void sends_counter_increment_to_statsd() throws Exception { assertThat(server.messagesReceived(), contains("my.prefix.myinc:1|c")); } - @Test(timeout = 5000L) + @Test//(timeout = 5000L) public void sends_counter_increment_to_statsd_with_tags() throws Exception { @@ -541,6 +539,30 @@ public void init_client_from_env_vars() throws Exception { assertThat(server.messagesReceived(), contains("my.prefix.value:423|g")); } + @Test(timeout = 5000L) + public void checkEnvVars() { + final Random r = new Random(); + for (final NonBlockingStatsDClient.Literal literal : NonBlockingStatsDClient.Literal.values()) { + final String envVarName = literal.envName(); + final String randomString = envVarName + "_val_" +r.nextDouble(); + environmentVariables.set(envVarName, randomString); + final NonBlockingStatsDClient client = new NonBlockingStatsDClientBuilder() + .prefix("checkEnvVars") + .hostname("localhost") + .port(STATSD_SERVER_PORT) + .build(); + server.clear(); + client.gauge("value", 42); + server.waitForMessage(); + assertThat(server.messagesReceived(), contains("checkEnvVars.value:42|g|#" + + literal.tag() + ":" + randomString)); + server.clear(); + + environmentVariables.clear(envVarName); + log.info("passed for '" + literal + "'; env cleaned."); + } + } + @Test(timeout = 5000L) public void sends_gauge_empty_prefix() throws Exception {