Skip to content

Commit 67daa75

Browse files
committed
[AST-494] request-id distributed logging interceptor
1 parent 8e58f1b commit 67daa75

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

grpc-context-utils/src/main/java/org/hypertrace/core/grpcutils/context/RequestContext.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ public static RequestContext forTenantId(String tenantId) {
4747
FastUUIDGenerator.randomUUID().toString());
4848
}
4949

50+
public static RequestContext withRequestId(String tenantId, String requestId) {
51+
return new RequestContext()
52+
.put(RequestContextConstants.TENANT_ID_HEADER_KEY, tenantId)
53+
.put(RequestContextConstants.REQUEST_ID_HEADER_KEY, requestId);
54+
}
55+
5056
public static RequestContext fromMetadata(Metadata metadata) {
5157
RequestContext requestContext = new RequestContext();
5258

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.hypertrace.core.grpcutils.server;
2+
3+
import static org.hypertrace.core.grpcutils.context.RequestContextConstants.REQUEST_ID_HEADER_KEY;
4+
5+
import io.grpc.Context;
6+
import io.grpc.Contexts;
7+
import io.grpc.ForwardingServerCallListener;
8+
import io.grpc.Metadata;
9+
import io.grpc.ServerCall;
10+
import io.grpc.ServerCallHandler;
11+
import io.grpc.ServerInterceptor;
12+
import java.util.Optional;
13+
import java.util.UUID;
14+
import lombok.extern.slf4j.Slf4j;
15+
import org.hypertrace.core.grpcutils.context.RequestContext;
16+
import org.slf4j.MDC;
17+
18+
@Slf4j
19+
public final class RequestContextLoggingServerInterceptor implements ServerInterceptor {
20+
21+
@Override
22+
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(
23+
ServerCall<ReqT, RespT> serverCall,
24+
Metadata metadata,
25+
ServerCallHandler<ReqT, RespT> serverCallHandler) {
26+
RequestContext currentContext =
27+
Optional.ofNullable(RequestContext.CURRENT.get())
28+
.orElseGet(() -> RequestContext.fromMetadata(metadata));
29+
Optional<String> opRequestId = currentContext.getHeaderValue(REQUEST_ID_HEADER_KEY);
30+
if (opRequestId.isEmpty()) {
31+
opRequestId = Optional.of(UUID.randomUUID().toString());
32+
}
33+
final String requestId = opRequestId.get();
34+
ServerCall.Listener<ReqT> listener =
35+
Contexts.interceptCall(
36+
Context.current().withValue(RequestContext.CURRENT, currentContext),
37+
serverCall,
38+
metadata,
39+
serverCallHandler);
40+
return new ForwardingServerCallListener.SimpleForwardingServerCallListener<>(listener) {
41+
42+
@Override
43+
public void onCancel() {
44+
try {
45+
MDC.clear();
46+
} catch (Exception e) {
47+
log.error("Error while clearing request context details from MDC params", e);
48+
}
49+
super.onCancel();
50+
}
51+
52+
@Override
53+
public void onComplete() {
54+
try {
55+
MDC.clear();
56+
} catch (Exception e) {
57+
log.error("Error while clearing request context details from MDC params", e);
58+
}
59+
super.onComplete();
60+
}
61+
62+
@Override
63+
public void onMessage(ReqT message) {
64+
try {
65+
MDC.put(REQUEST_ID_HEADER_KEY, requestId);
66+
} catch (Exception e) {
67+
log.error("Error while setting request context details in MDC params", e);
68+
}
69+
super.onMessage(message);
70+
}
71+
};
72+
}
73+
}

0 commit comments

Comments
 (0)