Update deps and OC instrumentation.

This commit is contained in:
Bogdan Drutu 2019-01-23 14:33:04 -08:00
parent ea424cb9f7
commit 928b6cc1e5
3 changed files with 87 additions and 99 deletions

View file

@ -23,10 +23,10 @@ repositories {
} }
group = "adservice" group = "adservice"
version = "0.1.0-SNAPSHOT" // CURRENT_OPENCENSUS_VERSION version = "0.1.0-SNAPSHOT"
def opencensusVersion = "0.17.0" // LATEST_OPENCENSUS_RELEASE_VERSION def opencensusVersion = "0.18.0"
def grpcVersion = "1.15.0" // CURRENT_GRPC_VERSION def grpcVersion = "1.17.0"
def jacksonVersion = "2.9.6" def jacksonVersion = "2.9.6"
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
@ -43,7 +43,9 @@ dependencies {
if (speed) { if (speed) {
compile fileTree(dir: offlineCompile, include: '*.jar') compile fileTree(dir: offlineCompile, include: '*.jar')
} else { } else {
compile "com.google.api.grpc:proto-google-common-protos:1.11.0", compile "com.google.api.grpc:proto-google-common-protos:1.12.0",
"io.opencensus:opencensus-api:${opencensusVersion}",
"io.opencensus:opencensus-contrib-grpc-util:${opencensusVersion}",
"io.opencensus:opencensus-exporter-trace-jaeger:${opencensusVersion}", "io.opencensus:opencensus-exporter-trace-jaeger:${opencensusVersion}",
"io.opencensus:opencensus-exporter-stats-stackdriver:${opencensusVersion}", "io.opencensus:opencensus-exporter-stats-stackdriver:${opencensusVersion}",
"io.opencensus:opencensus-exporter-trace-stackdriver:${opencensusVersion}", "io.opencensus:opencensus-exporter-trace-stackdriver:${opencensusVersion}",

View file

@ -29,20 +29,16 @@ import io.grpc.health.v1.HealthCheckResponse.ServingStatus;
import io.grpc.stub.StreamObserver; import io.grpc.stub.StreamObserver;
import io.grpc.services.*; import io.grpc.services.*;
import io.opencensus.common.Duration; import io.opencensus.common.Duration;
import io.opencensus.common.Scope;
import io.opencensus.contrib.grpc.metrics.RpcViews; import io.opencensus.contrib.grpc.metrics.RpcViews;
import io.opencensus.exporter.trace.jaeger.JaegerTraceExporter; import io.opencensus.exporter.trace.jaeger.JaegerTraceExporter;
import io.opencensus.exporter.trace.logging.LoggingTraceExporter;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration; import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter; import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration; import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter; import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter;
import io.opencensus.trace.AttributeValue; import io.opencensus.trace.AttributeValue;
import io.opencensus.trace.Span; import io.opencensus.trace.Span;
import io.opencensus.trace.SpanBuilder;
import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracer;
import io.opencensus.trace.Tracing; import io.opencensus.trace.Tracing;
import io.opencensus.trace.samplers.Samplers;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.ArrayList; import java.util.ArrayList;
@ -53,16 +49,17 @@ import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
public class AdService { public final class AdService {
private static final Logger logger = LogManager.getLogger(AdService.class);
private static final Logger logger = LogManager.getLogger(AdService.class);
private static final Tracer tracer = Tracing.getTracer(); private static final Tracer tracer = Tracing.getTracer();
private int MAX_ADS_TO_SERVE = 2; private static int MAX_ADS_TO_SERVE = 2;
private Server server; private Server server;
private HealthStatusManager healthMgr; private HealthStatusManager healthMgr;
static final AdService service = new AdService(); private static final AdService service = new AdService();
private void start() throws IOException { private void start() throws IOException {
int port = Integer.parseInt(System.getenv("PORT")); int port = Integer.parseInt(System.getenv("PORT"));
healthMgr = new HealthStatusManager(); healthMgr = new HealthStatusManager();
@ -91,26 +88,20 @@ public class AdService {
} }
} }
static class AdServiceImpl extends hipstershop.AdServiceGrpc.AdServiceImplBase { private static class AdServiceImpl extends hipstershop.AdServiceGrpc.AdServiceImplBase {
/** /**
* Retrieves ads based on context provided in the request {@code AdRequest}. * Retrieves ads based on context provided in the request {@code AdRequest}.
* *
* @param req the request containing context. * @param req the request containing context.
* @param responseObserver the stream observer which gets notified with the value of * @param responseObserver the stream observer which gets notified with the value of {@code
* {@code AdResponse} * AdResponse}
*/ */
@Override @Override
public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) { public void getAds(AdRequest req, StreamObserver<AdResponse> responseObserver) {
AdService service = AdService.getInstance(); AdService service = AdService.getInstance();
Span parentSpan = tracer.getCurrentSpan(); Span span = tracer.getCurrentSpan();
SpanBuilder spanBuilder = try {
tracer
.spanBuilderWithExplicitParent("Retrieve Ads", parentSpan)
.setRecordEvents(true)
.setSampler(Samplers.alwaysSample());
try (Scope scope = spanBuilder.startScopedSpan()) {
Span span = tracer.getCurrentSpan();
span.putAttribute("method", AttributeValue.stringAttributeValue("getAds")); span.putAttribute("method", AttributeValue.stringAttributeValue("getAds"));
List<Ad> allAds = new ArrayList<>(); List<Ad> allAds = new ArrayList<>();
logger.info("received ad request (context_words=" + req.getContextKeysList() + ")"); logger.info("received ad request (context_words=" + req.getContextKeysList() + ")");
@ -140,40 +131,42 @@ public class AdService {
responseObserver.onCompleted(); responseObserver.onCompleted();
} catch (StatusRuntimeException e) { } catch (StatusRuntimeException e) {
logger.log(Level.WARN, "GetAds Failed", e.getStatus()); logger.log(Level.WARN, "GetAds Failed", e.getStatus());
return; responseObserver.onError(e);
} }
} }
} }
static final ImmutableListMultimap<String, Ad> adsMap = createAdsMap(); private static final ImmutableListMultimap<String, Ad> adsMap = createAdsMap();
Collection<Ad> getAdsByCategory(String category) { private Collection<Ad> getAdsByCategory(String category) {
return adsMap.get(category); return adsMap.get(category);
} }
private static final Random random = new Random(); private static final Random random = new Random();
public List<Ad> getRandomAds() { private List<Ad> getRandomAds() {
List<Ad> ads = new ArrayList<>(MAX_ADS_TO_SERVE); List<Ad> ads = new ArrayList<>(MAX_ADS_TO_SERVE);
Collection<Ad> allAds = adsMap.values(); Collection<Ad> allAds = adsMap.values();
for (int i=0; i<MAX_ADS_TO_SERVE; i++) { for (int i = 0; i < MAX_ADS_TO_SERVE; i++) {
ads.add(Iterables.get(allAds, random.nextInt(allAds.size()))); ads.add(Iterables.get(allAds, random.nextInt(allAds.size())));
} }
return ads; return ads;
} }
public static AdService getInstance() { private static AdService getInstance() {
return service; return service;
} }
/** Await termination on the main thread since the grpc library uses daemon threads. */ /**
* Await termination on the main thread since the grpc library uses daemon threads.
*/
private void blockUntilShutdown() throws InterruptedException { private void blockUntilShutdown() throws InterruptedException {
if (server != null) { if (server != null) {
server.awaitTermination(); server.awaitTermination();
} }
} }
static ImmutableListMultimap<String, Ad> createAdsMap() { private static ImmutableListMultimap<String, Ad> createAdsMap() {
Ad camera = Ad.newBuilder().setRedirectUrl("/product/2ZYFJ3GM2N") Ad camera = Ad.newBuilder().setRedirectUrl("/product/2ZYFJ3GM2N")
.setText("Film camera for sale. 50% off.").build(); .setText("Film camera for sale. 50% off.").build();
Ad lens = Ad.newBuilder().setRedirectUrl("/product/66VCHSJNUP") Ad lens = Ad.newBuilder().setRedirectUrl("/product/66VCHSJNUP")
@ -197,7 +190,7 @@ public class AdService {
.build(); .build();
} }
public static void initStackdriver() { private static void initStackdriver() {
logger.info("Initialize StackDriver"); logger.info("Initialize StackDriver");
long sleepTime = 10; /* seconds */ long sleepTime = 10; /* seconds */
@ -205,7 +198,7 @@ public class AdService {
boolean statsExporterRegistered = false; boolean statsExporterRegistered = false;
boolean traceExporterRegistered = false; boolean traceExporterRegistered = false;
for (int i=0; i<maxAttempts; i++) { for (int i = 0; i < maxAttempts; i++) {
try { try {
if (!traceExporterRegistered) { if (!traceExporterRegistered) {
StackdriverTraceExporter.createAndRegister( StackdriverTraceExporter.createAndRegister(
@ -220,7 +213,7 @@ public class AdService {
statsExporterRegistered = true; statsExporterRegistered = true;
} }
} catch (Exception e) { } catch (Exception e) {
if (i==(maxAttempts-1)) { if (i == (maxAttempts - 1)) {
logger.log(Level.WARN, "Failed to register Stackdriver Exporter." + logger.log(Level.WARN, "Failed to register Stackdriver Exporter." +
" Tracing and Stats data will not reported to Stackdriver. Error message: " + e " Tracing and Stats data will not reported to Stackdriver. Error message: " + e
.toString()); .toString());
@ -237,7 +230,7 @@ public class AdService {
logger.info("StackDriver initialization complete."); logger.info("StackDriver initialization complete.");
} }
static void initJaeger() { private static void initJaeger() {
String jaegerAddr = System.getenv("JAEGER_SERVICE_ADDR"); String jaegerAddr = System.getenv("JAEGER_SERVICE_ADDR");
if (jaegerAddr != null && !jaegerAddr.isEmpty()) { if (jaegerAddr != null && !jaegerAddr.isEmpty()) {
String jaegerUrl = String.format("http://%s/api/traces", jaegerAddr); String jaegerUrl = String.format("http://%s/api/traces", jaegerAddr);
@ -249,18 +242,15 @@ public class AdService {
} }
} }
/** Main launches the server from the command line. */ /**
* Main launches the server from the command line.
*/
public static void main(String[] args) throws IOException, InterruptedException { public static void main(String[] args) throws IOException, InterruptedException {
// Add final keyword to pass checkStyle.
// Registers all RPC views. // Registers all RPC views.
RpcViews.registerAllViews(); RpcViews.registerAllGrpcViews();
// Registers logging trace exporter. new Thread(new Runnable() {
LoggingTraceExporter.register(); public void run() {
new Thread( new Runnable() {
public void run(){
initStackdriver(); initStackdriver();
} }
}).start(); }).start();

View file

@ -26,34 +26,36 @@ import io.grpc.StatusRuntimeException;
import io.opencensus.common.Duration; import io.opencensus.common.Duration;
import io.opencensus.common.Scope; import io.opencensus.common.Scope;
import io.opencensus.contrib.grpc.metrics.RpcViews; import io.opencensus.contrib.grpc.metrics.RpcViews;
import io.opencensus.exporter.trace.logging.LoggingTraceExporter; import io.opencensus.contrib.grpc.util.StatusConverter;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration; import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter; import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration; import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter; import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter;
import io.opencensus.trace.SpanBuilder; import io.opencensus.trace.Span;
import io.opencensus.trace.Status.CanonicalCode;
import io.opencensus.trace.Tracer; import io.opencensus.trace.Tracer;
import io.opencensus.trace.Tracing; import io.opencensus.trace.Tracing;
import io.opencensus.trace.samplers.Samplers; import io.opencensus.trace.samplers.Samplers;
import java.io.IOException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
/** A simple client that requests ads from the Ads Service. */ /**
* A simple client that requests ads from the Ads Service.
*/
public class AdServiceClient { public class AdServiceClient {
private static final Logger logger = LogManager.getLogger(AdServiceClient.class);
private static final Logger logger = LogManager.getLogger(AdServiceClient.class);
private static final Tracer tracer = Tracing.getTracer(); private static final Tracer tracer = Tracing.getTracer();
private final ManagedChannel channel; private final ManagedChannel channel;
private final hipstershop.AdServiceGrpc.AdServiceBlockingStub blockingStub; private final hipstershop.AdServiceGrpc.AdServiceBlockingStub blockingStub;
/** Construct client connecting to Ad Service at {@code host:port}. */ /**
public AdServiceClient(String host, int port) { * Construct client connecting to Ad Service at {@code host:port}.
*/
private AdServiceClient(String host, int port) {
this( this(
ManagedChannelBuilder.forAddress(host, port) ManagedChannelBuilder.forAddress(host, port)
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
@ -62,44 +64,48 @@ public class AdServiceClient {
.build()); .build());
} }
/** Construct client for accessing RouteGuide server using the existing channel. */ /**
AdServiceClient(ManagedChannel channel) { * Construct client for accessing RouteGuide server using the existing channel.
*/
private AdServiceClient(ManagedChannel channel) {
this.channel = channel; this.channel = channel;
blockingStub = hipstershop.AdServiceGrpc.newBlockingStub(channel); blockingStub = hipstershop.AdServiceGrpc.newBlockingStub(channel);
} }
public void shutdown() throws InterruptedException { private void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
} }
/** Get Ads from Server. */ /**
* Get Ads from Server.
*/
public void getAds(String contextKey) { public void getAds(String contextKey) {
logger.info("Get Ads with context " + contextKey + " ..."); logger.info("Get Ads with context " + contextKey + " ...");
AdRequest request = AdRequest.newBuilder().addContextKeys(contextKey).build(); AdRequest request = AdRequest.newBuilder().addContextKeys(contextKey).build();
AdResponse response; AdResponse response;
SpanBuilder spanBuilder = Span span =
tracer.spanBuilder("AdsClient").setRecordEvents(true).setSampler(Samplers.alwaysSample()); tracer.spanBuilder("AdsClient").setRecordEvents(true).setSampler(Samplers.alwaysSample())
try (Scope scope = spanBuilder.startScopedSpan()) { .startSpan();
try (Scope scope = tracer.withSpan(span)) {
tracer.getCurrentSpan().addAnnotation("Getting Ads"); tracer.getCurrentSpan().addAnnotation("Getting Ads");
response = blockingStub.getAds(request); response = blockingStub.getAds(request);
tracer.getCurrentSpan().addAnnotation("Received response from Ads Service."); tracer.getCurrentSpan().addAnnotation("Received response from Ads Service.");
} catch (StatusRuntimeException e) { } catch (StatusRuntimeException e) {
tracer tracer
.getCurrentSpan() .getCurrentSpan()
.setStatus( .setStatus(StatusConverter.fromGrpcStatus(e.getStatus()));
CanonicalCode.valueOf(e.getStatus().getCode().name()) logger.log(Level.WARN, "RPC failed: " + e.getStatus());
.toStatus()
.withDescription(e.getMessage()));
logger.log(Level.WARN, "RPC failed: {0}", e.getStatus());
return; return;
} finally {
span.end();
} }
for(Ad ads: response.getAdsList()) { for (Ad ads : response.getAdsList()) {
logger.info("Ads: " + ads.getText()); logger.info("Ads: " + ads.getText());
} }
} }
static int getPortOrDefaultFromArgs(String[] args, int index, int defaultPort) { private static int getPortOrDefaultFromArgs(String[] args, int index, int defaultPort) {
int portNumber = defaultPort; int portNumber = defaultPort;
if (index < args.length) { if (index < args.length) {
try { try {
@ -113,7 +119,7 @@ public class AdServiceClient {
} }
static String getStringOrDefaultFromArgs( private static String getStringOrDefaultFromArgs(
String[] args, int index, @Nullable String defaultString) { String[] args, int index, @Nullable String defaultString) {
String s = defaultString; String s = defaultString;
if (index < args.length) { if (index < args.length) {
@ -126,47 +132,37 @@ public class AdServiceClient {
* Ads Service Client main. If provided, the first element of {@code args} is the context key to * Ads Service Client main. If provided, the first element of {@code args} is the context key to
* get the ads from the Ads Service * get the ads from the Ads Service
*/ */
public static void main(String[] args) throws IOException, InterruptedException { public static void main(String[] args) throws InterruptedException {
// Add final keyword to pass checkStyle. // Add final keyword to pass checkStyle.
final String contextKeys = getStringOrDefaultFromArgs(args, 0, "camera"); final String contextKeys = getStringOrDefaultFromArgs(args, 0, "camera");
final String host = getStringOrDefaultFromArgs(args, 1, "localhost"); final String host = getStringOrDefaultFromArgs(args, 1, "localhost");
final int serverPort = getPortOrDefaultFromArgs(args, 2, 9555); final int serverPort = getPortOrDefaultFromArgs(args, 2, 9555);
final String cloudProjectId = getStringOrDefaultFromArgs(args, 3, null);
//final int zPagePort = getPortOrDefaultFromArgs(args, 4, 3001);
// Registers all RPC views. // Registers all RPC views.
RpcViews.registerAllViews(); RpcViews.registerAllGrpcViews();
// Registers logging trace exporter.
LoggingTraceExporter.register();
// Registers Stackdriver exporters. // Registers Stackdriver exporters.
if (cloudProjectId != null) { long sleepTime = 10; /* seconds */
long sleepTime = 10; /* seconds */ int maxAttempts = 3;
int maxAttempts = 3;
for (int i=0; i<maxAttempts; i++) { for (int i = 0; i < maxAttempts; i++) {
try { try {
StackdriverTraceExporter.createAndRegister( StackdriverTraceExporter.createAndRegister(StackdriverTraceConfiguration.builder().build());
StackdriverTraceConfiguration.builder().setProjectId(cloudProjectId).build()); StackdriverStatsExporter.createAndRegister(
StackdriverStatsExporter.createAndRegister( StackdriverStatsConfiguration.builder()
StackdriverStatsConfiguration.builder() .setExportInterval(Duration.create(15, 0))
.setProjectId(cloudProjectId) .build());
.setExportInterval(Duration.create(15, 0)) } catch (Exception e) {
.build()); if (i == (maxAttempts - 1)) {
} catch (Exception e) { logger.log(Level.WARN, "Failed to register Stackdriver Exporter." +
if (i==(maxAttempts-1)) { " Tracing and Stats data will not reported to Stackdriver. Error message: " + e
logger.log(Level.WARN, "Failed to register Stackdriver Exporter." + .toString());
" Tracing and Stats data will not reported to Stackdriver. Error message: " + e } else {
.toString()); logger.info("Attempt to register Stackdriver Exporter in " + sleepTime + " seconds");
} else { try {
logger.info("Attempt to register Stackdriver Exporter in " + sleepTime + " seconds"); Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime));
try { } catch (Exception se) {
Thread.sleep(TimeUnit.SECONDS.toMillis(sleepTime)); logger.log(Level.WARN, "Exception while sleeping" + e.toString());
} catch (Exception se) {
logger.log(Level.WARN, "Exception while sleeping" + e.toString());
}
} }
} }
} }