Skip to content
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

Add x-client-trace-id Header to All Requests #59

Merged
merged 2 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions java/src/main/java/utility/APISessionCredentials.java
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing the x-client-trace-id from this class as it's now being populated elsewhere

Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ public class APISessionCredentials extends CallCredentials {
public static final Metadata.Key<String> SESSION_TOKEN_KEY = keyOf("accessToken");
// Tenant Id of the customer org
public static final Metadata.Key<String> TENANT_ID_KEY = keyOf("tenantId");
// Client trace Id to trace the requests
public static final Metadata.Key<String> CLIENT_TRACE_ID_KEY = keyOf("x-client-trace-id");

private String instanceURL;
private String tenantId;
Expand All @@ -39,14 +37,11 @@ public APISessionCredentials(String tenantId, String instanceURL, String token)

@Override
public void applyRequestMetadata(RequestInfo requestInfo, Executor executor, MetadataApplier metadataApplier) {
String clientTraceId = UUID.randomUUID().toString();
log.info("Client Trace Id for current request: " + clientTraceId);
log.debug("API session credentials applied to " + requestInfo.getMethodDescriptor());
Metadata headers = new Metadata();
headers.put(INSTANCE_URL_KEY, instanceURL);
headers.put(TENANT_ID_KEY, tenantId);
headers.put(SESSION_TOKEN_KEY, token);
headers.put(CLIENT_TRACE_ID_KEY, clientTraceId);
metadataApplier.apply(headers);
}

Expand Down
6 changes: 4 additions & 2 deletions java/src/main/java/utility/CommonContext.java
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based on what I saw in the official interceptor docs as well as this Java sample

Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ public CommonContext(final ExampleConfigurations options) {
callCredentials = setupCallCredentials(options);
sessionToken = ((APISessionCredentials) callCredentials).getToken();

asyncStub = PubSubGrpc.newStub(channel).withCallCredentials(callCredentials);
blockingStub = PubSubGrpc.newBlockingStub(channel).withCallCredentials(callCredentials);
Channel interceptedChannel = ClientInterceptors.intercept(channel, new XClientTraceIdClientInterceptor());

asyncStub = PubSubGrpc.newStub(interceptedChannel).withCallCredentials(callCredentials);
blockingStub = PubSubGrpc.newBlockingStub(interceptedChannel).withCallCredentials(callCredentials);
}

/**
Expand Down
35 changes: 35 additions & 0 deletions java/src/main/java/utility/XClientTraceIdClientInterceptor.java
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

based on what I saw in the official interceptor docs as well as this Java sample

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package utility;

import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.grpc.*;

public class XClientTraceIdClientInterceptor implements ClientInterceptor {
private static final Logger logger = LoggerFactory.getLogger(XClientTraceIdClientInterceptor.class.getClass());
private static final Metadata.Key<String> X_CLIENT_TRACE_ID = Metadata.Key.of("x-client-trace-id", Metadata.ASCII_STRING_MARSHALLER);

@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
CallOptions callOptions, Channel next) {
return new ForwardingClientCall.SimpleForwardingClientCall<>(next.newCall(method, callOptions)) {

@Override
public void start(Listener<RespT> responseListener, Metadata headers) {
String xClientTraceId = UUID.randomUUID().toString();
headers.put(X_CLIENT_TRACE_ID, xClientTraceId);
logger.info("sending request for xClientTraceId {}", xClientTraceId);

super.start(new ForwardingClientCallListener.SimpleForwardingClientCallListener<>(responseListener) {
@Override
public void onClose(Status status, Metadata trailers) {
logger.info("request completed for xClientTraceId {} with status {}", xClientTraceId, status);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This differs slightly from the Java example (linked above), but the intention here is to basically just log the x-client-trace-id that was passed any time a request completes. This log line should be hit whether the request completes successfully or with an error. I'll include some sample output below

example log for a successful call:

request completed for xClientTraceId 8895e3a5-65d9-4428-bc1e-6e991838f164 with status Status{code=OK, description=null, cause=null}

example log for a failed call:

request completed for xClientTraceId eb62166d-5126-4b52-857b-ed73c2d3018e with status Status{code=UNAVAILABLE, description=RST_STREAM closed stream. HTTP/2 error code: NO_ERROR, cause=null}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice find. Curious, how did you generate the RST_STREAM error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used the Subscribe example to open a subscription then killed the backend server that was serving the subscription

super.onClose(status, trailers);
}
}, headers);
}
};
}
}