New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphite: Replace names with non-alphanumeric chars with '-' #938

Merged
merged 1 commit into from Apr 11, 2016
Jump to file or symbol
Failed to load files and symbols.
+101 −11
Diff settings

Always

Just for now

Graphite: Replace names with non-alphanumeric chars with '-'

  • Loading branch information...
nickbabcock committed Apr 11, 2016
commit a3e96ee69159877c7cd5b29e37184a7a9292ecd2
@@ -8,15 +8,12 @@
import java.io.IOException;
import java.net.Socket;
import java.nio.charset.Charset;
import java.util.regex.Pattern;
/**
* A rabbit-mq client to a Carbon server.
*/
public class GraphiteRabbitMQ implements GraphiteSender {
private static final Pattern WHITESPACE = Pattern.compile("[\\s]+");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final Integer DEFAULT_RABBIT_CONNECTION_TIMEOUT_MS = 500;
@@ -161,7 +158,7 @@ public int getFailures() {
}
public String sanitize(String s) {
return WHITESPACE.matcher(s).replaceAll("-");
return GraphiteSanitize.sanitize(s, '-');
}
}
@@ -0,0 +1,71 @@
package com.codahale.metrics.graphite;
class GraphiteSanitize {
/** Replaces all characters from a given string that are not ascii and not alphanumeric
* with a dash */
static String sanitize(String string, char replacement) {
String replaced = replaceFrom(string, replacement);
// Consolidate multiple dashes into a single one
String result = replaced.replace("--", "-");
while (!result.equals(replaced)) {
replaced = result;
result = replaced.replace("--", "-");
}
// Remove any leading or trailing dashes
return strip(result, replacement);
}
/** A char matches when it is a letter or digit and it is ASCII, in Guava terminology,
* this would be CharMatcher.ASCII.and(CharMatcher.JAVA_LETTER_OR_DIGIT).negate() */
private static boolean matches(char c) {
return !(Character.isLetterOrDigit(c) && c <= '\u007f');
}
/** Replace all characters that we're interested in with a replacement character,
* heavily inspired by the same code in Guava's CharMatcher */
private static String replaceFrom(String string, char replacement) {
int pos = indexIn(string, 0);
if (pos == -1) {
return string;
}
char[] chars = string.toCharArray();
chars[pos] = replacement;
for (int i = pos + 1; i < chars.length; i++) {
if (matches(chars[i])) {
chars[i] = replacement;
}
}
return new String(chars).trim();
}
/** Finds the first index (or -1) of a character we're interested in */
private static int indexIn(String sequence, int start) {
int length = sequence.length();
for (int i = start; i < length; i++) {
if (matches(sequence.charAt(i))) {
return i;
}
}
return -1;
}
/** Strips a given character from the beginning and end of a string,
* heavily inspired by Apache's StringUtils.strip
*/
private static String strip(String str, char strip) {
int strLen = str.length();
int start = 0;
int end = strLen - 1;
while (start != strLen && str.charAt(start) == strip) {
start++;
}
while (end > start && str.charAt(end) == strip) {
end--;
}
return start != 0 || end != strLen - 1 ? str.substring(start, end + 1) : str;
}
}
@@ -5,15 +5,12 @@
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.Charset;
import java.util.regex.Pattern;
/**
* A client to a Carbon server using unconnected UDP
*/
public class GraphiteUDP implements GraphiteSender {
private static final Pattern WHITESPACE = Pattern.compile("[\\s]+");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final String hostname;
@@ -111,7 +108,7 @@ public void close() throws IOException {
}
protected String sanitize(String s) {
return WHITESPACE.matcher(s).replaceAll("-");
return GraphiteSanitize.sanitize(s, '-');
}
}
@@ -18,14 +18,12 @@
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
/**
* A client to a Carbon server that sends all metrics after they have been pickled in configurable sized batches
*/
public class PickledGraphite implements GraphiteSender {
private static final Pattern WHITESPACE = Pattern.compile("[\\s]+");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private static final Logger LOGGER = LoggerFactory.getLogger(PickledGraphite.class);
@@ -360,7 +358,7 @@ private void writeMetrics() throws IOException {
}
protected String sanitize(String s) {
return WHITESPACE.matcher(s).replaceAll("-");
return GraphiteSanitize.sanitize(s, '-');
}
}
@@ -0,0 +1,27 @@
package com.codahale.metrics.graphite;
import org.assertj.core.api.SoftAssertions;
import org.junit.Test;
public class GraphiteSanitizeTest {
@Test
public void sanitizeGraphiteValues() {
SoftAssertions softly = new SoftAssertions();
softly.assertThat(GraphiteSanitize.sanitize("Foo Bar", '-')).isEqualTo("Foo-Bar");
softly.assertThat(GraphiteSanitize.sanitize(" Foo Bar ", '-')).isEqualTo("Foo-Bar");
softly.assertThat(GraphiteSanitize.sanitize(" Foo Bar", '-')).isEqualTo("Foo-Bar");
softly.assertThat(GraphiteSanitize.sanitize("Foo Bar ", '-')).isEqualTo("Foo-Bar");
softly.assertThat(GraphiteSanitize.sanitize(" Foo Bar ", '-')).isEqualTo("Foo-Bar");
softly.assertThat(GraphiteSanitize.sanitize("Foo@Bar", '-')).isEqualTo("Foo-Bar");
softly.assertThat(GraphiteSanitize.sanitize("Foó Bar", '-')).isEqualTo("Fo-Bar");
softly.assertThat(GraphiteSanitize.sanitize("||ó/.", '-')).isEqualTo("");
softly.assertThat(GraphiteSanitize.sanitize("${Foo:Bar:baz}", '-')).isEqualTo("Foo-Bar-baz");
softly.assertThat(GraphiteSanitize.sanitize("St. Foo's of Bar", '-')).isEqualTo("St-Foo-s-of-Bar");
softly.assertThat(GraphiteSanitize.sanitize("(Foo and (Bar and (Baz)))", '-')).isEqualTo("Foo-and-Bar-and-Baz");
softly.assertThat(GraphiteSanitize.sanitize("Foo.bar.baz", '-')).isEqualTo("Foo-bar-baz");
softly.assertThat(GraphiteSanitize.sanitize("FooBar", '-')).isEqualTo("FooBar");
softly.assertAll();
}
}
ProTip! Use n and p to navigate between commits in a pull request.