Skip to content

Commit 7696082

Browse files
authored
Adds http.method tag by default and removes bad naming advice (#616)
This adds the http.method tag by default as many frameworks override the span name, or will as soon as http.route is supported. This allows users to always see basic http info at the cost of a small, fixed cardinality tag. Users who really don't want to see this tag can already disable parsing of it by overriding the default parser. This also removes the bad advice from the README, which hinted at using a path as a span name. This will result in ever-expanding span name index when there are path variables. The http route based approach is superior and merges next.
1 parent 5bea163 commit 7696082

File tree

3 files changed

+30
-9
lines changed

3 files changed

+30
-9
lines changed

instrumentation/http/README.md

+8-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ instructions on what to put into http spans, and sampling policy.
1111
By default, the following are added to both http client and server spans:
1212
* Span.name as the http method in lowercase: ex "get"
1313
* Tags/binary annotations:
14+
* "http.method", eg "GET"
1415
* "http.path", which does not include query parameters.
1516
* "http.status_code" when the status us not success.
1617
* "error", when there is an exception or status is >=400
@@ -20,15 +21,14 @@ Naming and tags are configurable in a library-agnostic way. For example,
2021
the same `HttpTracing` component configures OkHttp or Apache HttpClient
2122
identically.
2223

23-
For example, to change the span and tag naming policy for clients, you
24-
can do something like this:
24+
For example, to change the tagging policy for clients, you can do
25+
something like this:
2526

2627
```java
2728
httpTracing = httpTracing.toBuilder()
2829
.clientParser(new HttpClientParser() {
2930
@Override
3031
public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) {
31-
customizer.name(adapter.method(req).toLowerCase() + " " + adapter.path(req));
3232
customizer.tag(TraceKeys.HTTP_URL, adapter.url(req)); // the whole url, not just the path
3333
}
3434
})
@@ -38,8 +38,8 @@ apache = TracingHttpClientBuilder.create(httpTracing.clientOf("s3"));
3838
okhttp = TracingCallFactory.create(httpTracing.clientOf("sqs"), new OkHttpClient());
3939
```
4040

41-
If you just want to control span naming policy, override `spanName` in
42-
your client or server parser.
41+
If you just want to control span naming policy based on the request,
42+
override `spanName` in your client or server parser.
4343

4444
Ex:
4545
```java
@@ -50,6 +50,9 @@ overrideSpanName = new HttpClientParser() {
5050
};
5151
```
5252

53+
Note that span name can be overwritten any time, for example, when
54+
parsing the response.
55+
5356
## Sampling Policy
5457
The default sampling policy is to use the default (trace ID) sampler for
5558
server and client requests.

instrumentation/http/src/main/java/brave/http/HttpParser.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,22 @@
66
public class HttpParser {
77
/**
88
* Override to change what data from the http request are parsed into the span representing it. By
9-
* default, this sets the span name to the http method and tags "http.path"
9+
* default, this sets the span name to the http method and tags "http.method" and "http.path".
1010
*
1111
* <p>If you only want to change the span name, you can override {@link #spanName(HttpAdapter,
1212
* Object)} instead.
1313
*
1414
* @see #spanName(HttpAdapter, Object)
1515
*/
16+
// Eventhough the default span name is the method, we have no way of knowing that a user hasn't
17+
// overwritten the name to something else. If that occurs during response parsing, it is too late
18+
// to go back and get the http method. Adding http method by default ensures span naming doesn't
19+
// prevent basic HTTP info from being visible. A cost of this is another tag, but it is small with
20+
// very limited cardinality. Moreover, users who care strictly about size can override this.
1621
public <Req> void request(HttpAdapter<Req, ?> adapter, Req req, SpanCustomizer customizer) {
1722
customizer.name(spanName(adapter, req));
23+
String method = adapter.method(req);
24+
if (method != null) customizer.tag("http.method", method);
1825
String path = adapter.path(req);
1926
if (path != null) customizer.tag("http.path", path);
2027
}
@@ -66,7 +73,7 @@ protected void error(@Nullable Integer httpStatus, @Nullable Throwable error,
6673
if (error != null) {
6774
message = error.getMessage();
6875
if (message == null) message = error.getClass().getSimpleName();
69-
} else if (httpStatus != null) {
76+
} else if (httpStatus != null && httpStatus != 0) {
7077
message = httpStatus < 200 || httpStatus > 399 ? String.valueOf(httpStatus) : null;
7178
}
7279
if (message != null) customizer.tag("error", message);

instrumentation/http/src/test/java/brave/http/HttpParserTest.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ public class HttpParserTest {
2323
when(adapter.method(request)).thenReturn("GET");
2424

2525
assertThat(parser.spanName(adapter, request))
26-
.isEqualTo("GET");
26+
.isEqualTo("GET"); // note: in practice this will become lowercase
2727
}
2828

29-
@Test public void request_addsPath() {
29+
@Test public void request_addsMethodAndPath() {
30+
when(adapter.method(request)).thenReturn("GET");
3031
when(adapter.path(request)).thenReturn("/foo");
3132

3233
parser.request(adapter, request, customizer);
3334

35+
verify(customizer).tag("http.method", "GET");
3436
verify(customizer).tag("http.path", "/foo");
3537
}
3638

@@ -49,6 +51,15 @@ public class HttpParserTest {
4951
verify(customizer).tag("error", "400");
5052
}
5153

54+
@Test public void response_statusZeroIsNotAnError() {
55+
when(adapter.statusCodeAsInt(response)).thenReturn(0);
56+
57+
parser.response(adapter, response, null, customizer);
58+
59+
verify(customizer, never()).tag("http.status_code", "0");
60+
verify(customizer, never()).tag("error", "0");
61+
}
62+
5263
@Test public void response_tagsErrorFromException() {
5364
parser.response(adapter, response, new RuntimeException("drat"), customizer);
5465

0 commit comments

Comments
 (0)