Skip to content

Commit

Permalink
Use string value of the status code number
Browse files Browse the repository at this point in the history
  • Loading branch information
Mateusz Rzeszutek committed Oct 10, 2023
1 parent f1915b5 commit 9b1f3e8
Show file tree
Hide file tree
Showing 16 changed files with 171 additions and 478 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ public void onEnd(

if (SemconvStability.emitStableHttpSemconv()) {
String errorType;
if (statusCode != null && statusCode > 0) {
errorType = statusCodeConverter.getErrorType(statusCode);
if (statusCode != null && statusCodeConverter.isError(statusCode)) {
errorType = statusCode.toString();
} else {
errorType = getter.getErrorType(request, response, error);
// fall back to exception class name & _OTHER
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ public void extract(
if (response != null) {
Integer statusCode = getter.getHttpResponseStatusCode(request, response, error);
if (statusCode != null) {
StatusCode statusCodeObj = statusCodeConverter.getSpanStatus(statusCode);
if (statusCodeObj == StatusCode.ERROR) {
spanStatusBuilder.setStatus(statusCodeObj);
if (statusCodeConverter.isError(statusCode)) {
spanStatusBuilder.setStatus(StatusCode.ERROR);
return;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,104 +5,26 @@

package io.opentelemetry.instrumentation.api.instrumenter.http;

import static java.util.Collections.unmodifiableMap;

import io.opentelemetry.api.trace.StatusCode;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nullable;

// https://github.com/open-telemetry/semantic-conventions/blob/v1.21.0/docs/http/http-spans.md#status
enum HttpStatusCodeConverter {
SERVER {

@Override
StatusCode getSpanStatus(int responseStatusCode) {
if (responseStatusCode >= 100 && responseStatusCode < 500) {
return StatusCode.UNSET;
}

return StatusCode.ERROR;
}

@Nullable
@Override
String getErrorType(int responseStatusCode) {
return serverErrorTypes.get(responseStatusCode);
boolean isError(int responseStatusCode) {
return responseStatusCode >= 500
||
// invalid status code, does not exists
responseStatusCode < 100;
}
},
CLIENT {
@Override
StatusCode getSpanStatus(int responseStatusCode) {
if (responseStatusCode >= 100 && responseStatusCode < 400) {
return StatusCode.UNSET;
}

return StatusCode.ERROR;
}

@Nullable
@Override
String getErrorType(int responseStatusCode) {
return clientErrorTypes.get(responseStatusCode);
boolean isError(int responseStatusCode) {
return responseStatusCode >= 400
||
// invalid status code, does not exists
responseStatusCode < 100;
}
};

abstract StatusCode getSpanStatus(int responseStatusCode);

@Nullable
abstract String getErrorType(int responseStatusCode);

private static final Map<Integer, String> serverErrorTypes;
private static final Map<Integer, String> clientErrorTypes;

// https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
static {
Map<Integer, String> serverPhrases = new HashMap<>();
serverPhrases.put(500, "Internal Server Error");
serverPhrases.put(501, "Not Implemented");
serverPhrases.put(502, "Bad Gateway");
serverPhrases.put(503, "Service Unavailable");
serverPhrases.put(504, "Gateway Timeout");
serverPhrases.put(505, "HTTP Version Not Supported");
serverPhrases.put(506, "Variant Also Negotiates");
serverPhrases.put(507, "Insufficient Storage");
serverPhrases.put(508, "Loop Detected");
serverPhrases.put(510, "Not Extended");
serverPhrases.put(511, "Network Authentication Required");
serverErrorTypes = unmodifiableMap(serverPhrases);

// include all server error types
Map<Integer, String> clientPhrases = new HashMap<>(serverPhrases);
clientPhrases.put(400, "Bad Request");
clientPhrases.put(401, "Unauthorized");
clientPhrases.put(402, "Payment Required");
clientPhrases.put(403, "Forbidden");
clientPhrases.put(404, "Not Found");
clientPhrases.put(405, "Method Not Allowed");
clientPhrases.put(406, "Not Acceptable");
clientPhrases.put(407, "Proxy Authentication Required");
clientPhrases.put(408, "Request Timeout");
clientPhrases.put(409, "Conflict");
clientPhrases.put(410, "Gone");
clientPhrases.put(411, "Length Required");
clientPhrases.put(412, "Precondition Failed");
clientPhrases.put(413, "Content Too Large");
clientPhrases.put(414, "URI Too Long");
clientPhrases.put(415, "Unsupported Media Type");
clientPhrases.put(416, "Range Not Satisfiable");
clientPhrases.put(417, "Expectation Failed");
clientPhrases.put(418, "I'm a teapot");
clientPhrases.put(421, "Misdirected Request");
clientPhrases.put(422, "Unprocessable Content");
clientPhrases.put(423, "Locked");
clientPhrases.put(424, "Failed Dependency");
clientPhrases.put(425, "Too Early");
clientPhrases.put(426, "Upgrade Required");
clientPhrases.put(428, "Precondition Required");
clientPhrases.put(429, "Too Many Requests");
clientPhrases.put(431, "Request Header Fields Too Large");
clientPhrases.put(451, "Unavailable For Legal Reasons");
clientErrorTypes = unmodifiableMap(clientPhrases);
}
abstract boolean isError(int responseStatusCode);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ class HttpSpanStatusExtractorTest {
@ParameterizedTest
@ValueSource(ints = {1, 100, 101, 200, 201, 300, 301, 500, 501, 600, 601})
void hasServerStatus(int statusCode) {
StatusCode expectedStatusCode = HttpStatusCodeConverter.SERVER.getSpanStatus(statusCode);
boolean isError = HttpStatusCodeConverter.SERVER.isError(statusCode);
when(serverGetter.getHttpResponseStatusCode(anyMap(), anyMap(), isNull()))
.thenReturn(statusCode);

HttpSpanStatusExtractor.create(serverGetter)
.extract(spanStatusBuilder, Collections.emptyMap(), Collections.emptyMap(), null);

if (expectedStatusCode != StatusCode.UNSET) {
verify(spanStatusBuilder).setStatus(expectedStatusCode);
if (isError) {
verify(spanStatusBuilder).setStatus(StatusCode.ERROR);
} else {
verifyNoInteractions(spanStatusBuilder);
}
Expand All @@ -51,15 +51,15 @@ void hasServerStatus(int statusCode) {
@ParameterizedTest
@ValueSource(ints = {1, 100, 101, 200, 201, 300, 301, 400, 401, 500, 501, 600, 601})
void hasClientStatus(int statusCode) {
StatusCode expectedStatusCode = HttpStatusCodeConverter.CLIENT.getSpanStatus(statusCode);
boolean isError = HttpStatusCodeConverter.CLIENT.isError(statusCode);
when(clientGetter.getHttpResponseStatusCode(anyMap(), anyMap(), isNull()))
.thenReturn(statusCode);

HttpSpanStatusExtractor.create(clientGetter)
.extract(spanStatusBuilder, Collections.emptyMap(), Collections.emptyMap(), null);

if (expectedStatusCode != StatusCode.UNSET) {
verify(spanStatusBuilder).setStatus(expectedStatusCode);
if (isError) {
verify(spanStatusBuilder).setStatus(StatusCode.ERROR);
} else {
verifyNoInteractions(spanStatusBuilder);
}
Expand Down
Loading

0 comments on commit 9b1f3e8

Please sign in to comment.