Skip to content

Distributted logging for scan-id#90

Draft
Mayur-Rokade78 wants to merge 4 commits intomainfrom
distributted-logging
Draft

Distributted logging for scan-id#90
Mayur-Rokade78 wants to merge 4 commits intomainfrom
distributted-logging

Conversation

@Mayur-Rokade78
Copy link
Collaborator

Description

Please include a summary of the change, motivation and context.

Testing

Please describe the tests that you ran to verify your changes. Please summarize what did you test and what needs to be tested e.g. deployed and tested helm chart locally.

Checklist:

  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • Any dependent changes have been merged and published in downstream modules

Documentation

Make sure that you have documented corresponding changes in this repository or hypertrace docs repo if required.

@github-actions
Copy link

github-actions bot commented Mar 3, 2026

Test Results

98 tests  ±0   98 ✅ ±0   29s ⏱️ +3s
16 suites ±0    0 💤 ±0 
16 files   ±0    0 ❌ ±0 

Results for commit de6ab58. ± Comparison against base commit cc38c52.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to support distributed logging/correlation for scan workflows by introducing an x-ctx-* header namespace (including scan-id), ensuring these headers are propagated through RequestContext, and surfacing them in server-side MDC for log enrichment.

Changes:

  • Add CTX_HEADER_PREFIX (x-ctx-) and propagate all matching headers via RequestContextConstants.HEADER_PREFIXES_TO_BE_PROPAGATED.
  • Enhance RequestContextLoggingServerInterceptor to copy all x-ctx-* headers into SLF4J MDC.
  • Introduce ScanMetadataBuilder to construct gRPC Metadata containing tenant-id, request-id, and x-ctx-scan-id.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
grpc-server-utils/src/main/java/org/hypertrace/core/grpcutils/server/RequestContextLoggingServerInterceptor.java Adds MDC enrichment for all x-ctx-* headers on inbound requests.
grpc-context-utils/src/main/java/org/hypertrace/core/grpcutils/context/ScanMetadataBuilder.java New helper to build outbound gRPC metadata including scan-id.
grpc-context-utils/src/main/java/org/hypertrace/core/grpcutils/context/RequestContextConstants.java Adds x-ctx- prefix constant and includes it in propagated header prefixes.
Comments suppressed due to low confidence (1)

grpc-context-utils/src/main/java/org/hypertrace/core/grpcutils/context/RequestContextConstants.java:37

  • Adding CTX_HEADER_PREFIX to HEADER_PREFIXES_TO_BE_PROPAGATED changes RequestContext.fromMetadata(...) behavior to now include all x-ctx-* headers. There are existing unit tests around metadata propagation (RequestContextTest.testMetadataKeys), but none covering this new prefix. Consider extending those tests to assert that an x-ctx-* header (e.g., x-ctx-scan-id) is preserved when building a RequestContext from gRPC Metadata.
  public static final String CTX_HEADER_PREFIX = "x-ctx-";

  /** The values in this set are looked up with case insensitivity. */
  public static final Set<String> HEADER_PREFIXES_TO_BE_PROPAGATED =
      Set.of(
          TENANT_ID_HEADER_KEY,
          CONTEXT_ID_HEADER_KEY,
          SUPPRESS_USER_TRACKING_HEADER_KEY,
          CTX_HEADER_PREFIX,
          "X-B3-",
          "grpc-trace-bin",
          "traceparent",
          "tracestate",
          AUTHORIZATION_HEADER,
          REQUEST_ID_HEADER_KEY);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

opTenantId.ifPresent(s -> MDC.put(TENANT_ID_HEADER_KEY, s));
opContextId.ifPresent(s -> MDC.put(CONTEXT_ID_HEADER_KEY, s));
currentContext.getAllHeaders().stream()
.filter(header -> header.getName().startsWith(CTX_HEADER_PREFIX))
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

The startsWith(CTX_HEADER_PREFIX) check is case-sensitive, but RequestContext preserves the original header name case (e.g., a caller could have put X-CTX-scan-id). This can cause x-ctx-* headers to be skipped and not logged in MDC. Consider performing a case-insensitive prefix check (e.g., compare on toLowerCase() or use regionMatches(true, ...)).

Suggested change
.filter(header -> header.getName().startsWith(CTX_HEADER_PREFIX))
.filter(
header ->
header
.getName()
.regionMatches(
true, 0, CTX_HEADER_PREFIX, 0, CTX_HEADER_PREFIX.length()))

Copilot uses AI. Check for mistakes.
opTenantId.ifPresent(s -> MDC.put(TENANT_ID_HEADER_KEY, s));
opContextId.ifPresent(s -> MDC.put(CONTEXT_ID_HEADER_KEY, s));
currentContext.getAllHeaders().stream()
.filter(header -> header.getName().startsWith(CTX_HEADER_PREFIX))
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

RequestContext.put(...) allows null header values, but this code unconditionally calls MDC.put(header.getName(), header.getValue()). SLF4J MDC implementations commonly reject null values (and even if allowed, it can lead to confusing log output). Consider filtering out headers with null values (similar to RequestContextAsCreds.applyRequestContext) or using MDC.remove(key) when the value is null.

Suggested change
.filter(header -> header.getName().startsWith(CTX_HEADER_PREFIX))
.filter(header -> header.getName().startsWith(CTX_HEADER_PREFIX))
.filter(header -> header.getValue() != null)

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +75
currentContext.getAllHeaders().stream()
.filter(header -> header.getName().startsWith(CTX_HEADER_PREFIX))
.forEach(header -> MDC.put(header.getName(), header.getValue()));
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

This change introduces new behavior (propagating all x-ctx-* headers into MDC) but grpc-server-utils currently has no test coverage for RequestContextLoggingServerInterceptor. Adding a unit test that asserts x-ctx-* headers appear in MDC on onMessage() and are cleared on onComplete()/onCancel() would help prevent regressions.

Copilot uses AI. Check for mistakes.

public class ScanMetadataBuilder {

public static final String CTX_SCAN_ID_HEADER_KEY = "x-ctx-scan-id";
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

CTX_SCAN_ID_HEADER_KEY is a request-context header constant, but it's defined in ScanMetadataBuilder rather than alongside the other shared header constants in RequestContextConstants (e.g., TENANT_ID_HEADER_KEY, REQUEST_ID_HEADER_KEY, CTX_HEADER_PREFIX). Moving it (and optionally a Metadata.Key<String> form) into RequestContextConstants would make it easier for other modules to consistently reference the same header name and avoid duplication.

Suggested change
public static final String CTX_SCAN_ID_HEADER_KEY = "x-ctx-scan-id";
private static final String CTX_SCAN_ID_HEADER_KEY = "x-ctx-scan-id";

Copilot uses AI. Check for mistakes.
Comment on lines +12 to +18
public static Metadata build(String tenantId, String requestId, String scanId) {
Metadata metadata = new Metadata();
metadata.put(Metadata.Key.of(TENANT_ID_HEADER_KEY, Metadata.ASCII_STRING_MARSHALLER), tenantId);
metadata.put(
Metadata.Key.of(REQUEST_ID_HEADER_KEY, Metadata.ASCII_STRING_MARSHALLER), requestId);
metadata.put(Metadata.Key.of(CTX_SCAN_ID_HEADER_KEY, Metadata.ASCII_STRING_MARSHALLER), scanId);
return metadata;
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

ScanMetadataBuilder is a new API surface for constructing outbound metadata, but there are no unit tests validating that the expected keys/values are set (tenant, request-id, and scan-id). Since grpc-context-utils already has a test suite, adding a small test for ScanMetadataBuilder.build(...) would help catch accidental header name regressions.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants