Skip to content

Commit 48e9b9c

Browse files
authored
Merge pull request quarkusio#48037 from brunobat/micrometer-optimizations-1
Remove regex from hot path in micrometer
2 parents 43cd492 + 3b166b7 commit 48e9b9c

File tree

2 files changed

+55
-7
lines changed

2 files changed

+55
-7
lines changed

extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/binder/RequestMetricInfo.java

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
public class RequestMetricInfo {
1212
static final Logger log = Logger.getLogger(RequestMetricInfo.class);
1313

14-
public static final Pattern TRAILING_SLASH_PATTERN = Pattern.compile("/$");
15-
public static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("//+");
1614
public static final String ROOT = "/";
1715

1816
public static final String HTTP_REQUEST_PATH = "HTTP_REQUEST_PATH";
@@ -85,12 +83,30 @@ protected static String normalizePath(String uri) {
8583
if (uri == null || uri.isEmpty() || ROOT.equals(uri)) {
8684
return ROOT;
8785
}
88-
// Label value consistency: result should begin with a '/' and should not end with one
89-
String workingPath = MULTIPLE_SLASH_PATTERN.matcher('/' + uri).replaceAll("/");
90-
workingPath = TRAILING_SLASH_PATTERN.matcher(workingPath).replaceAll("");
91-
if (workingPath.isEmpty()) {
92-
return ROOT;
86+
87+
String workingPath = new String(uri);
88+
89+
// Remove all leading slashes
90+
// detect
91+
int start = 0;
92+
while (start < workingPath.length() && workingPath.charAt(start) == '/') {
93+
start++;
9394
}
95+
// Add missing / and remove multiple leading
96+
if (start != 1) {
97+
workingPath = "/" + workingPath.substring(start);
98+
}
99+
100+
// Collapse multiple trailing slashes
101+
int end = workingPath.length();
102+
while (end > 1 && workingPath.charAt(end - 1) == '/') {
103+
end--;
104+
}
105+
106+
if (end != workingPath.length()) {
107+
workingPath = workingPath.substring(0, end);
108+
}
109+
94110
return workingPath;
95111
}
96112
}

extensions/micrometer/runtime/src/test/java/io/quarkus/micrometer/runtime/binder/RequestMetricInfoTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,57 @@ public void init() {
3232
requestMetric = new RequestMetricInfo();
3333
}
3434

35+
@Test
36+
public void testParsePathSingleSlash() {
37+
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, NO_IGNORE_PATTERNS, "/");
38+
Assertions.assertEquals("/", path);
39+
}
40+
3541
@Test
3642
public void testParsePathDoubleSlash() {
3743
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, NO_IGNORE_PATTERNS, "//");
3844
Assertions.assertEquals("/", path);
3945
}
4046

47+
@Test
48+
public void testParsePathMultipleSlash() {
49+
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, NO_IGNORE_PATTERNS, "/////");
50+
Assertions.assertEquals("/", path);
51+
}
52+
4153
@Test
4254
public void testParseEmptyPath() {
4355
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, NO_IGNORE_PATTERNS, "");
4456
Assertions.assertEquals("/", path);
4557
}
4658

59+
@Test
60+
public void testParseNullPath() {
61+
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, NO_IGNORE_PATTERNS, null);
62+
Assertions.assertEquals("/", path);
63+
}
64+
4765
@Test
4866
public void testParsePathNoLeadingSlash() {
4967
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, NO_IGNORE_PATTERNS,
5068
"path/with/no/leading/slash");
5169
Assertions.assertEquals("/path/with/no/leading/slash", path);
5270
}
5371

72+
@Test
73+
public void testParsePathNoEndSlash() {
74+
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, NO_IGNORE_PATTERNS,
75+
"/path/with/no/end/slash/");
76+
Assertions.assertEquals("/path/with/no/end/slash", path);
77+
}
78+
79+
@Test
80+
public void testParsePathNoEndDoubleSlash() {
81+
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, NO_IGNORE_PATTERNS,
82+
"/path/with/no/end/double/slash///////");
83+
Assertions.assertEquals("/path/with/no/end/double/slash", path);
84+
}
85+
5486
@Test
5587
public void testParsePathIgnoreNoLeadingSlash() {
5688
String path = requestMetric.getNormalizedUriPath(NO_MATCH_PATTERNS, ignorePatterns,

0 commit comments

Comments
 (0)