From 570f533c5c0d37058900fcae3d788fd0729417fc Mon Sep 17 00:00:00 2001 From: Simon Stewart Date: Sat, 10 Nov 2018 22:56:36 +0000 Subject: [PATCH] Wire tracing into the node --- .../selenium/remote/tracing/CompoundSpan.java | 6 + .../remote/tracing/DistributedTracer.java | 2 +- .../remote/tracing/OpenCensusSpan.java | 9 ++ .../remote/tracing/OpenTracingSpan.java | 7 ++ .../openqa/selenium/remote/tracing/Span.java | 2 + .../selenium/grid/commands/Standalone.java | 8 +- .../selenium/grid/distributor/AddNode.java | 18 ++- .../org/openqa/selenium/grid/node/Node.java | 12 +- .../selenium/grid/node/httpd/NodeServer.java | 5 +- .../selenium/grid/node/local/LocalNode.java | 108 ++++++++++-------- .../selenium/grid/node/remote/RemoteNode.java | 4 +- .../grid/distributor/DistributorTest.java | 9 +- .../openqa/selenium/grid/node/NodeTest.java | 22 ++-- .../selenium/grid/router/EndToEndTest.java | 5 +- 14 files changed, 148 insertions(+), 69 deletions(-) diff --git a/java/client/src/org/openqa/selenium/remote/tracing/CompoundSpan.java b/java/client/src/org/openqa/selenium/remote/tracing/CompoundSpan.java index 59b7aacd442db..5c20e4f35dcc6 100644 --- a/java/client/src/org/openqa/selenium/remote/tracing/CompoundSpan.java +++ b/java/client/src/org/openqa/selenium/remote/tracing/CompoundSpan.java @@ -52,6 +52,12 @@ public Span createChild(String operation) { return child.activate(); } + @Override + public Span setName(String name) { + allSpans.forEach(span -> span.setName(name)); + return this; + } + @Override public Span addTraceTag(String key, String value) { Objects.requireNonNull(key, "Key must be set"); diff --git a/java/client/src/org/openqa/selenium/remote/tracing/DistributedTracer.java b/java/client/src/org/openqa/selenium/remote/tracing/DistributedTracer.java index 044a5b944c557..25f32a76c31e3 100644 --- a/java/client/src/org/openqa/selenium/remote/tracing/DistributedTracer.java +++ b/java/client/src/org/openqa/selenium/remote/tracing/DistributedTracer.java @@ -48,7 +48,7 @@ public static DistributedTracer getInstance() { return INSTANCE; } - public synchronized void setInstance(DistributedTracer distributedTracer) { + public synchronized static void setInstance(DistributedTracer distributedTracer) { INSTANCE = distributedTracer; } diff --git a/java/client/src/org/openqa/selenium/remote/tracing/OpenCensusSpan.java b/java/client/src/org/openqa/selenium/remote/tracing/OpenCensusSpan.java index b8ec56a0e9cb5..b7f7040e42d5d 100644 --- a/java/client/src/org/openqa/selenium/remote/tracing/OpenCensusSpan.java +++ b/java/client/src/org/openqa/selenium/remote/tracing/OpenCensusSpan.java @@ -48,6 +48,15 @@ public Span activate() { return this; } + @Override + public Span setName(String name) { + Objects.requireNonNull(name, "Name must be set."); + + // TODO: Actually change the name of the span + + return this; + } + @Override public Span addTraceTag(String key, String value) { span.putAttribute(Objects.requireNonNull(key), AttributeValue.stringAttributeValue(value)); diff --git a/java/client/src/org/openqa/selenium/remote/tracing/OpenTracingSpan.java b/java/client/src/org/openqa/selenium/remote/tracing/OpenTracingSpan.java index 199d0843013f0..265dfde5c4e85 100644 --- a/java/client/src/org/openqa/selenium/remote/tracing/OpenTracingSpan.java +++ b/java/client/src/org/openqa/selenium/remote/tracing/OpenTracingSpan.java @@ -59,6 +59,13 @@ public Span activate() { return this; } + @Override + public Span setName(String name) { + Objects.requireNonNull(name, "Name must be set."); + span.setOperationName(name); + return this; + } + @Override public Span addTraceTag(String key, String value) { span.setBaggageItem(Objects.requireNonNull(key), value); diff --git a/java/client/src/org/openqa/selenium/remote/tracing/Span.java b/java/client/src/org/openqa/selenium/remote/tracing/Span.java index 14512905090f6..6b5b861e60023 100644 --- a/java/client/src/org/openqa/selenium/remote/tracing/Span.java +++ b/java/client/src/org/openqa/selenium/remote/tracing/Span.java @@ -30,6 +30,8 @@ public abstract class Span implements Closeable { */ public abstract Span activate(); + public abstract Span setName(String name); + /** * Add a tag that will be transmitted across the wire to allow remote traces * to also have the value. This is equivalent to OpenTracing's concept of diff --git a/java/server/src/org/openqa/selenium/grid/commands/Standalone.java b/java/server/src/org/openqa/selenium/grid/commands/Standalone.java index c71007272b0d3..87f9dfdd84f9e 100644 --- a/java/server/src/org/openqa/selenium/grid/commands/Standalone.java +++ b/java/server/src/org/openqa/selenium/grid/commands/Standalone.java @@ -114,15 +114,15 @@ public Executable configure(String... args) { throw new RuntimeException(e); } - LocalNode.Builder node = LocalNode.builder(localhost, sessions) + DistributedTracer tracer = DistributedTracer.getInstance(); + + LocalNode.Builder node = LocalNode.builder(tracer, localhost, sessions) .maximumConcurrentSessions(Runtime.getRuntime().availableProcessors() * 3); nodeFlags.configure(node); distributor.add(node.build()); - Server server = new BaseServer<>( - DistributedTracer.getInstance(), - new BaseServerOptions(config)); + Server server = new BaseServer<>(tracer, new BaseServerOptions(config)); server.addRoute(Routes.matching(router).using(router).decorateWith(W3CCommandHandler.class)); server.start(); }; diff --git a/java/server/src/org/openqa/selenium/grid/distributor/AddNode.java b/java/server/src/org/openqa/selenium/grid/distributor/AddNode.java index 0e77184439d2a..2e27c9561925e 100644 --- a/java/server/src/org/openqa/selenium/grid/distributor/AddNode.java +++ b/java/server/src/org/openqa/selenium/grid/distributor/AddNode.java @@ -29,6 +29,7 @@ import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; +import org.openqa.selenium.remote.tracing.DistributedTracer; import java.io.IOException; import java.net.URI; @@ -42,11 +43,17 @@ public class AddNode implements CommandHandler { + private final DistributedTracer tracer; private final Distributor distributor; private final Json json; private final HttpClient.Factory httpFactory; - public AddNode(Distributor distributor, Json json, HttpClient.Factory httpFactory) { + public AddNode( + DistributedTracer tracer, + Distributor distributor, + Json json, + HttpClient.Factory httpFactory) { + this.tracer = Objects.requireNonNull(tracer); this.distributor = Objects.requireNonNull(distributor); this.json = Objects.requireNonNull(json); this.httpFactory = Objects.requireNonNull(httpFactory); @@ -57,7 +64,7 @@ public void execute(HttpRequest req, HttpResponse resp) throws IOException { Map raw = json.toType(req.getContentString(), MAP_TYPE); UUID id = UUID.fromString((String) raw.get("id")); - URI uri = null; + URI uri; try { uri = new URI((String) raw.get("uri")); } catch (URISyntaxException e) { @@ -71,7 +78,12 @@ public void execute(HttpRequest req, HttpResponse resp) throws IOException { .map(ImmutableCapabilities::new) .collect(Collectors.toList()); - Node node = new RemoteNode(id, uri, capabilities, httpFactory.createClient(uri.toURL())); + Node node = new RemoteNode( + tracer, + id, + uri, + capabilities, + httpFactory.createClient(uri.toURL())); distributor.add(node); } diff --git a/java/server/src/org/openqa/selenium/grid/node/Node.java b/java/server/src/org/openqa/selenium/grid/node/Node.java index 3510b09c71a5e..83b795abc85b5 100644 --- a/java/server/src/org/openqa/selenium/grid/node/Node.java +++ b/java/server/src/org/openqa/selenium/grid/node/Node.java @@ -34,6 +34,8 @@ import org.openqa.selenium.remote.SessionId; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; +import org.openqa.selenium.remote.tracing.DistributedTracer; +import org.openqa.selenium.remote.tracing.Span; import java.io.IOException; import java.util.Objects; @@ -90,17 +92,20 @@ */ public abstract class Node implements Predicate, CommandHandler { + private final DistributedTracer tracer; private final UUID id; private final Injector injector; private final Routes routes; - protected Node(UUID id) { + protected Node(DistributedTracer tracer, UUID id) { + this.tracer = Objects.requireNonNull(tracer); this.id = Objects.requireNonNull(id); Json json = new Json(); injector = Injector.builder() .register(this) .register(json) + .register(tracer) .build(); routes = combine( @@ -156,4 +161,9 @@ public void execute(HttpRequest req, HttpResponse resp) throws IOException { } handler.get().execute(req, resp); } + + protected Span createSpan(String operationName) { + Objects.requireNonNull(operationName); + return tracer.createSpan(operationName, tracer.getActiveSpan()); + } } diff --git a/java/server/src/org/openqa/selenium/grid/node/httpd/NodeServer.java b/java/server/src/org/openqa/selenium/grid/node/httpd/NodeServer.java index 11c9186275411..c939cbb85c144 100644 --- a/java/server/src/org/openqa/selenium/grid/node/httpd/NodeServer.java +++ b/java/server/src/org/openqa/selenium/grid/node/httpd/NodeServer.java @@ -108,7 +108,10 @@ public Executable configure(String... args) { BaseServerOptions serverOptions = new BaseServerOptions(config); - LocalNode.Builder builder = LocalNode.builder(serverOptions.getExternalUri(), sessions); + LocalNode.Builder builder = LocalNode.builder( + DistributedTracer.getInstance(), + serverOptions.getExternalUri(), + sessions); nodeFlags.configure(builder); LocalNode node = builder.build(); diff --git a/java/server/src/org/openqa/selenium/grid/node/local/LocalNode.java b/java/server/src/org/openqa/selenium/grid/node/local/LocalNode.java index ffbc8c1bf24b5..b070600b6dea8 100644 --- a/java/server/src/org/openqa/selenium/grid/node/local/LocalNode.java +++ b/java/server/src/org/openqa/selenium/grid/node/local/LocalNode.java @@ -35,6 +35,8 @@ import org.openqa.selenium.remote.SessionId; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; +import org.openqa.selenium.remote.tracing.DistributedTracer; +import org.openqa.selenium.remote.tracing.Span; import java.io.IOException; import java.io.UncheckedIOException; @@ -58,12 +60,13 @@ public class LocalNode extends Node { private final Cache currentSessions; private LocalNode( + DistributedTracer tracer, URI uri, int maxSessionCount, Ticker ticker, Duration sessionTimeout, List factories) { - super(UUID.randomUUID()); + super(tracer, UUID.randomUUID()); Preconditions.checkArgument( maxSessionCount > 0, @@ -92,65 +95,78 @@ public boolean isSupporting(Capabilities capabilities) { @Override public Optional newSession(Capabilities capabilities) { - if (getCurrentSessionCount() >= maxSessionCount) { - return Optional.empty(); - } + try (Span span = createSpan("node-new-session")) { + span.addTag("capabilities", capabilities.toString()); + if (getCurrentSessionCount() >= maxSessionCount) { + return Optional.empty(); + } - Optional possibleSession = factories.stream() - .filter(factory -> factory.test(capabilities)) - .map(factory -> factory.apply(capabilities)) - .filter(Optional::isPresent) - .findFirst() - .map(Optional::get); + Optional possibleSession = factories.stream() + .filter(factory -> factory.test(capabilities)) + .map(factory -> factory.apply(capabilities)) + .filter(Optional::isPresent) + .findFirst() + .map(Optional::get); - if (!possibleSession.isPresent()) { - return Optional.empty(); - } + if (!possibleSession.isPresent()) { + return Optional.empty(); + } - SessionAndHandler session = possibleSession.get(); - currentSessions.put(session.getId(), session); + SessionAndHandler session = possibleSession.get(); + currentSessions.put(session.getId(), session); - // The session we return has to look like it came from the node, since we might be dealing - // with a webdriver implementation that only accepts connections from localhost - return Optional.of(new Session(session.getId(), externalUri, session.getCapabilities())); + // The session we return has to look like it came from the node, since we might be dealing + // with a webdriver implementation that only accepts connections from localhost + return Optional.of(new Session(session.getId(), externalUri, session.getCapabilities())); + } } @Override protected boolean isSessionOwner(SessionId id) { - Objects.requireNonNull(id, "Session ID has not been set"); - return currentSessions.getIfPresent(id) != null; + try (Span span = createSpan("node-is-session-owner")) { + span.addTag("session-id", String.valueOf(id)); + Objects.requireNonNull(id, "Session ID has not been set"); + return currentSessions.getIfPresent(id) != null; + } } @Override public Session getSession(SessionId id) throws NoSuchSessionException { - Objects.requireNonNull(id, "Session ID has not been set"); - SessionAndHandler session = currentSessions.getIfPresent(id); - if (session == null) { - throw new NoSuchSessionException("Cannot find session with id: " + id); - } + try (Span span = createSpan("node-get-session")) { + span.addTag("session-id", String.valueOf(id)); + Objects.requireNonNull(id, "Session ID has not been set"); + SessionAndHandler session = currentSessions.getIfPresent(id); + if (session == null) { + throw new NoSuchSessionException("Cannot find session with id: " + id); + } - return new Session(session.getId(), externalUri, session.getCapabilities()); + return new Session(session.getId(), externalUri, session.getCapabilities()); + } } @Override public void executeWebDriverCommand(HttpRequest req, HttpResponse resp) { - // True enough to be good enough - if (!req.getUri().startsWith("/session/")) { - throw new UnsupportedCommandException(String.format( - "Unsupported command: (%s) %s", req.getMethod(), req.getMethod())); - } + try (Span span = createSpan("node-execute-webdriver-command")) { + // True enough to be good enough + if (!req.getUri().startsWith("/session/")) { + throw new UnsupportedCommandException(String.format( + "Unsupported command: (%s) %s", req.getMethod(), req.getMethod())); + } - String[] split = req.getUri().split("/", 4); - SessionId id = new SessionId(split[2]); + String[] split = req.getUri().split("/", 4); + SessionId id = new SessionId(split[2]); - SessionAndHandler session = currentSessions.getIfPresent(id); - if (session == null) { - throw new NoSuchSessionException("Cannot find session with id: " + id); - } - try { - session.getHandler().execute(req, resp); - } catch (IOException e) { - throw new UncheckedIOException(e); + span.addTag("session-id", String.valueOf(id)); + + SessionAndHandler session = currentSessions.getIfPresent(id); + if (session == null) { + throw new NoSuchSessionException("Cannot find session with id: " + id); + } + try { + session.getHandler().execute(req, resp); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } } @@ -195,12 +211,13 @@ private Map toJson() { .collect(Collectors.toSet())); } - public static Builder builder(URI uri, SessionMap sessions) { - return new Builder(uri, sessions); + public static Builder builder(DistributedTracer tracer, URI uri, SessionMap sessions) { + return new Builder(tracer, uri, sessions); } public static class Builder { + private final DistributedTracer tracer; private final URI uri; private final SessionMap sessions; private final ImmutableList.Builder factories; @@ -208,7 +225,8 @@ public static class Builder { private Ticker ticker = Ticker.systemTicker(); private Duration sessionTimeout = Duration.ofMinutes(5); - public Builder(URI uri, SessionMap sessions) { + public Builder(DistributedTracer tracer, URI uri, SessionMap sessions) { + this.tracer = Objects.requireNonNull(tracer); this.uri = Objects.requireNonNull(uri); this.sessions = Objects.requireNonNull(sessions); this.factories = ImmutableList.builder(); @@ -238,7 +256,7 @@ public Builder sessionTimeout(Duration timeout) { } public LocalNode build() { - return new LocalNode(uri, maxCount, ticker, sessionTimeout, factories.build()); + return new LocalNode(tracer, uri, maxCount, ticker, sessionTimeout, factories.build()); } public Advanced advanced() { diff --git a/java/server/src/org/openqa/selenium/grid/node/remote/RemoteNode.java b/java/server/src/org/openqa/selenium/grid/node/remote/RemoteNode.java index ee42c6ffbc897..09c4d65a334bb 100644 --- a/java/server/src/org/openqa/selenium/grid/node/remote/RemoteNode.java +++ b/java/server/src/org/openqa/selenium/grid/node/remote/RemoteNode.java @@ -36,6 +36,7 @@ import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; +import org.openqa.selenium.remote.tracing.DistributedTracer; import java.io.IOException; import java.io.UncheckedIOException; @@ -56,11 +57,12 @@ public class RemoteNode extends Node { private final Set capabilities; public RemoteNode( + DistributedTracer tracer, UUID id, URI externalUri, Collection capabilities, HttpClient client) { - super(id); + super(tracer, id); this.externalUri = Objects.requireNonNull(externalUri); this.capabilities = ImmutableSet.copyOf(capabilities); diff --git a/java/server/test/org/openqa/selenium/grid/distributor/DistributorTest.java b/java/server/test/org/openqa/selenium/grid/distributor/DistributorTest.java index f44108c80c51d..ebba3401cb7c3 100644 --- a/java/server/test/org/openqa/selenium/grid/distributor/DistributorTest.java +++ b/java/server/test/org/openqa/selenium/grid/distributor/DistributorTest.java @@ -33,6 +33,7 @@ import org.openqa.selenium.grid.web.PassthroughHttpClient; import org.openqa.selenium.remote.NewSessionPayload; import org.openqa.selenium.remote.SessionId; +import org.openqa.selenium.remote.tracing.DistributedTracer; import java.net.URI; import java.net.URISyntaxException; @@ -40,12 +41,14 @@ public class DistributorTest { + private DistributedTracer tracer; private Distributor local; private Distributor distributor; private ImmutableCapabilities caps; @Before public void setUp() { + tracer = DistributedTracer.builder().build(); local = new LocalDistributor(); distributor = new RemoteDistributor(new PassthroughHttpClient<>(local)); @@ -66,7 +69,7 @@ public void shouldBeAbleToAddANodeAndCreateASession() throws URISyntaxException URI routableUri = new URI("http://localhost:1234"); LocalSessionMap sessions = new LocalSessionMap(); - LocalNode node = LocalNode.builder(routableUri, sessions) + LocalNode node = LocalNode.builder(tracer, routableUri, sessions) .add(caps, c -> new Session(new SessionId(UUID.randomUUID()), nodeUri, c)) .build(); @@ -89,7 +92,7 @@ public void shouldBeAbleToRemoveANode() throws URISyntaxException { URI routableUri = new URI("http://localhost:1234"); LocalSessionMap sessions = new LocalSessionMap(); - LocalNode node = LocalNode.builder(routableUri, sessions) + LocalNode node = LocalNode.builder(tracer, routableUri, sessions) .add(caps, c -> new Session(new SessionId(UUID.randomUUID()), nodeUri, c)) .build(); @@ -111,7 +114,7 @@ public void registeringTheSameNodeMultipleTimesOnlyCountsTheFirstTime() URI routableUri = new URI("http://localhost:1234"); LocalSessionMap sessions = new LocalSessionMap(); - LocalNode node = LocalNode.builder(routableUri, sessions) + LocalNode node = LocalNode.builder(tracer, routableUri, sessions) .add(caps, c -> new Session(new SessionId(UUID.randomUUID()), nodeUri, c)) .build(); diff --git a/java/server/test/org/openqa/selenium/grid/node/NodeTest.java b/java/server/test/org/openqa/selenium/grid/node/NodeTest.java index 734a6c1d19034..e0f5f2a31d9cc 100644 --- a/java/server/test/org/openqa/selenium/grid/node/NodeTest.java +++ b/java/server/test/org/openqa/selenium/grid/node/NodeTest.java @@ -40,6 +40,7 @@ import org.openqa.selenium.remote.http.HttpClient; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; +import org.openqa.selenium.remote.tracing.DistributedTracer; import java.io.IOException; import java.net.URI; @@ -55,6 +56,7 @@ public class NodeTest { + private DistributedTracer tracer; private LocalNode local; private Node node; private ImmutableCapabilities caps; @@ -63,6 +65,8 @@ public class NodeTest { @Before public void setUp() throws URISyntaxException { + tracer = DistributedTracer.builder().build(); + caps = new ImmutableCapabilities("browserName", "cheese"); uri = new URI("http://localhost:1234"); @@ -81,7 +85,7 @@ public void execute(HttpRequest req, HttpResponse resp) { } } - local = LocalNode.builder(uri, sessions) + local = LocalNode.builder(tracer, uri, sessions) .add(caps, c -> new Handler(c)) .add(caps, c -> new Handler(c)) .add(caps, c -> new Handler(c)) @@ -90,6 +94,7 @@ public void execute(HttpRequest req, HttpResponse resp) { HttpClient client = new PassthroughHttpClient<>(local); node = new RemoteNode( + tracer, UUID.randomUUID(), uri, ImmutableSet.of(caps), @@ -98,9 +103,9 @@ public void execute(HttpRequest req, HttpResponse resp) { @Test public void shouldRefuseToCreateASessionIfNoFactoriesAttached() { - Node local = LocalNode.builder(uri, sessions).build(); + Node local = LocalNode.builder(tracer, uri, sessions).build(); HttpClient client = new PassthroughHttpClient<>(local); - Node node = new RemoteNode(UUID.randomUUID(), uri, ImmutableSet.of(), client); + Node node = new RemoteNode(tracer, UUID.randomUUID(), uri, ImmutableSet.of(), client); Optional session = node.newSession(caps); @@ -116,7 +121,7 @@ public void shouldCreateASessionIfTheCorrectCapabilitiesArePassedToIt() { @Test public void shouldOnlyCreateAsManySessionsAsFactories() { - Node node = LocalNode.builder(uri, sessions) + Node node = LocalNode.builder(tracer, uri, sessions) .add(caps, (c) -> new Session(new SessionId(UUID.randomUUID()), uri, c)) .build(); @@ -227,10 +232,11 @@ public void execute(HttpRequest req, HttpResponse resp) { } } - Node local = LocalNode.builder(uri, sessions) + Node local = LocalNode.builder(tracer, uri, sessions) .add(caps, c -> new Recording()) .build(); Node remote = new RemoteNode( + tracer, UUID.randomUUID(), uri, ImmutableSet.of(caps), @@ -264,7 +270,7 @@ public void aSessionThatTimesOutWillBeStoppedAndRemovedFromTheSessionMap() { AtomicReference now = new AtomicReference<>(Instant.now()); Clock clock = new MyClock(now); - Node node = LocalNode.builder(uri, sessions) + Node node = LocalNode.builder(tracer, uri, sessions) .add(caps, c -> new Session(new SessionId(UUID.randomUUID()), uri, c)) .sessionTimeout(Duration.ofMinutes(3)) .advanced() @@ -281,7 +287,7 @@ public void aSessionThatTimesOutWillBeStoppedAndRemovedFromTheSessionMap() { @Test public void shouldNotPropagateExceptionsWhenSessionCreationFails() { - Node local = LocalNode.builder(uri, sessions) + Node local = LocalNode.builder(tracer, uri, sessions) .add(caps, c -> { throw new SessionNotCreatedException("eeek"); }) @@ -315,4 +321,4 @@ public Instant instant() { return now.get(); } } -} \ No newline at end of file +} diff --git a/java/server/test/org/openqa/selenium/grid/router/EndToEndTest.java b/java/server/test/org/openqa/selenium/grid/router/EndToEndTest.java index b8b801026fbcb..b2e2c454c118d 100644 --- a/java/server/test/org/openqa/selenium/grid/router/EndToEndTest.java +++ b/java/server/test/org/openqa/selenium/grid/router/EndToEndTest.java @@ -53,6 +53,7 @@ public class EndToEndTest { private final Capabilities driverCaps = new ImmutableCapabilities("browserName", "cheese"); + private final DistributedTracer tracer = DistributedTracer.builder().build(); @Test public void inMemory() throws URISyntaxException { @@ -60,7 +61,7 @@ public void inMemory() throws URISyntaxException { SessionMap sessions = new LocalSessionMap(); Distributor distributor = new LocalDistributor(); URI nodeUri = new URI("http://localhost:4444"); - LocalNode node = LocalNode.builder(nodeUri, sessions) + LocalNode node = LocalNode.builder(tracer, nodeUri, sessions) .add(driverCaps, createFactory(nodeUri)) .build(); distributor.add(node); @@ -101,7 +102,7 @@ public void withServers() throws URISyntaxException { int port = PortProber.findFreePort(); URI nodeUri = new URI("http://localhost:" + port); - LocalNode localNode = LocalNode.builder(nodeUri, sessions) + LocalNode localNode = LocalNode.builder(tracer, nodeUri, sessions) .add(driverCaps, createFactory(nodeUri)) .build(); Server nodeServer = new BaseServer<>(