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

[adservice] - add manual tracing instrumentation #150

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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: 5 additions & 0 deletions src/adservice/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ description = 'Ad Service'
group = "adservice"
version = "0.1.0-SNAPSHOT"

def opentelemetryVersion = "1.12.0"
def grpcVersion = "1.45.1"
def jacksonVersion = "2.13.2"
def protocVersion = "3.20.0"
Expand All @@ -32,12 +33,16 @@ dependencies {
if (speed) {
implementation fileTree(dir: offlineCompile, include: '*.jar')
} else {

implementation "com.google.api.grpc:proto-google-common-protos:2.8.0",
"javax.annotation:javax.annotation-api:1.3.2",
"io.grpc:grpc-protobuf:${grpcVersion}",
"io.grpc:grpc-stub:${grpcVersion}",
"io.grpc:grpc-netty:${grpcVersion}",
"io.grpc:grpc-services:${grpcVersion}",
"io.opentelemetry:opentelemetry-api:${opentelemetryVersion}",
"io.opentelemetry:opentelemetry-sdk:${opentelemetryVersion}",
"io.opentelemetry:opentelemetry-extension-annotations:${opentelemetryVersion}",
"org.apache.logging.log4j:log4j-core:2.17.2"

runtimeOnly "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}",
Expand Down
48 changes: 42 additions & 6 deletions src/adservice/src/main/java/hipstershop/AdService.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@
import io.grpc.health.v1.HealthCheckResponse.ServingStatus;
import io.grpc.protobuf.services.*;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.extension.annotations.SpanAttribute;
import io.opentelemetry.extension.annotations.WithSpan;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
Expand All @@ -41,7 +50,7 @@ public final class AdService {
private static final Logger logger = LogManager.getLogger(AdService.class);

@SuppressWarnings("FieldCanBeLocal")
private static int MAX_ADS_TO_SERVE = 2;
private static final int MAX_ADS_TO_SERVE = 2;

private Server server;
private HealthStatusManager healthMgr;
Expand Down Expand Up @@ -91,8 +100,14 @@ private static class AdServiceImpl extends hipstershop.AdServiceGrpc.AdServiceIm
@Override
public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) {
AdService service = AdService.getInstance();

// get the current span in context
Span span = Span.current();
try {
List<Ad> allAds = new ArrayList<>();

span.setAttribute("app.ads.contextKeys", req.getContextKeysList().toString());
span.setAttribute("app.ads.contextKeys.count", req.getContextKeysCount());
mic-max marked this conversation as resolved.
Show resolved Hide resolved
logger.info("received ad request (context_words=" + req.getContextKeysList() + ")");
if (req.getContextKeysCount() > 0) {
for (int i = 0; i < req.getContextKeysCount(); i++) {
Expand All @@ -106,10 +121,13 @@ public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) {
// Serve random ads.
allAds = service.getRandomAds();
}
span.setAttribute("app.ads.count", allAds.size());
AdResponse reply = AdResponse.newBuilder().addAllAds(allAds).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
} catch (StatusRuntimeException e) {
span.addEvent("Error", Attributes.of(AttributeKey.stringKey("exception.message"), e.getMessage()));
span.setStatus(StatusCode.ERROR);
puckpuck marked this conversation as resolved.
Show resolved Hide resolved
logger.log(Level.WARN, "GetAds Failed with status {}", e.getStatus());
responseObserver.onError(e);
}
Expand All @@ -118,18 +136,36 @@ public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) {

private static final ImmutableListMultimap<String, Ad> adsMap = createAdsMap();

private Collection<Ad> getAdsByCategory(String category) {
return adsMap.get(category);
@WithSpan("getAdsByCategory")
private Collection<Ad> getAdsByCategory(@SpanAttribute("app.ads.category") String category) {
Collection<Ad> ads = adsMap.get(category);
Span.current().setAttribute("app.ads.count", ads.size());
return ads;
}

private static final Random random = new Random();

private List<Ad> getRandomAds() {

List<Ad> ads = new ArrayList<>(MAX_ADS_TO_SERVE);
Collection<Ad> allAds = adsMap.values();
for (int i = 0; i < MAX_ADS_TO_SERVE; i++) {
ads.add(Iterables.get(allAds, random.nextInt(allAds.size())));

// create and start a new span manually
Tracer tracer = GlobalOpenTelemetry.getTracer("");
Span span = tracer.spanBuilder("getRandomAds").startSpan();

// put the span into context, so if any child span is started the parent will be set properly
try (Scope ignored = span.makeCurrent()) {

Collection<Ad> allAds = adsMap.values();
for (int i = 0; i < MAX_ADS_TO_SERVE; i++) {
ads.add(Iterables.get(allAds, random.nextInt(allAds.size())));
}
span.setAttribute("app.ads.count", ads.size());
austinlparker marked this conversation as resolved.
Show resolved Hide resolved

} finally {
span.end();
}

return ads;
}

Expand Down