Skip to content

Commit 4fbf058

Browse files
committed
Get log capture working in the new servlet.
Hardly elegant, but it now appears to capture a lot of the same information, so we're making progress.
1 parent 29f7d46 commit 4fbf058

File tree

4 files changed

+83
-6
lines changed

4 files changed

+83
-6
lines changed

java/server/src/org/openqa/selenium/remote/server/BeginSession.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,20 @@
2323

2424
import com.google.common.collect.ImmutableMap;
2525

26+
import com.sun.javafx.util.Logging;
27+
2628
import org.openqa.selenium.SessionNotCreatedException;
29+
import org.openqa.selenium.logging.LogType;
30+
import org.openqa.selenium.logging.LoggingPreferences;
2731
import org.openqa.selenium.remote.BeanToJsonConverter;
2832
import org.openqa.selenium.remote.http.HttpRequest;
2933
import org.openqa.selenium.remote.http.HttpResponse;
34+
import org.openqa.selenium.remote.server.log.LoggingManager;
3035

3136
import java.io.IOException;
3237
import java.io.InputStreamReader;
3338
import java.io.Reader;
39+
import java.util.logging.Level;
3440

3541
class BeginSession implements CommandHandler {
3642

@@ -63,6 +69,13 @@ public void execute(HttpRequest req, HttpResponse resp) throws IOException {
6369
allSessions.put(session);
6470
}
6571

72+
// Force capture of server-side logs since we don't have easy access to the request from the
73+
// local end.
74+
LoggingPreferences loggingPrefs = new LoggingPreferences();
75+
loggingPrefs.enable(LogType.SERVER, Level.INFO);
76+
LoggingManager.perSessionLogHandler().configureLogging(loggingPrefs);
77+
LoggingManager.perSessionLogHandler().attachToCurrentThread(session.getId());
78+
6679
Object toConvert;
6780
switch (session.getDownstreamDialect()) {
6881
case OSS:

java/server/src/org/openqa/selenium/remote/server/WebDriverServlet.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,27 @@
2323
import static org.openqa.selenium.remote.CapabilityType.BROWSER_NAME;
2424
import static org.openqa.selenium.remote.server.DriverServlet.SESSION_TIMEOUT_PARAMETER;
2525

26+
import com.google.common.base.Splitter;
2627
import com.google.common.net.HttpHeaders;
2728
import com.google.common.net.MediaType;
2829

30+
import org.openqa.selenium.logging.LoggingHandler;
31+
import org.openqa.selenium.remote.SessionId;
32+
import org.openqa.selenium.remote.server.log.LoggingManager;
33+
import org.openqa.selenium.remote.server.log.PerSessionLogHandler;
2934
import org.openqa.selenium.remote.server.xdrpc.CrossDomainRpc;
3035
import org.openqa.selenium.remote.server.xdrpc.CrossDomainRpcLoader;
3136

3237
import java.io.ByteArrayInputStream;
3338
import java.io.IOException;
39+
import java.util.List;
3440
import java.util.concurrent.ExecutionException;
3541
import java.util.concurrent.ExecutorService;
3642
import java.util.concurrent.Executors;
3743
import java.util.concurrent.Future;
3844
import java.util.concurrent.TimeoutException;
45+
import java.util.logging.Handler;
46+
import java.util.logging.Logger;
3947

4048
import javax.servlet.ServletException;
4149
import javax.servlet.ServletInputStream;
@@ -46,6 +54,7 @@
4654

4755
public class WebDriverServlet extends HttpServlet {
4856

57+
private static final Logger LOG = Logger.getLogger(WebDriverServlet.class.getName());
4958
public static final String ACTIVE_SESSIONS_KEY = WebDriverServlet.class.getName() + ".sessions";
5059

5160
private static final String CROSS_DOMAIN_RPC_PATH = "/xdrpc";
@@ -57,6 +66,7 @@ public class WebDriverServlet extends HttpServlet {
5766

5867
@Override
5968
public void init() throws ServletException {
69+
configureLogging();
6070
log("Initialising WebDriverServlet");
6171

6272
String value = getInitParameter(SESSION_TIMEOUT_PARAMETER);
@@ -73,6 +83,22 @@ public void init() throws ServletException {
7383
handlers = new AllHandlers(allSessions);
7484
}
7585

86+
private synchronized Logger configureLogging() {
87+
Logger logger = Logger.getGlobal();
88+
logger.addHandler(LoggingHandler.getInstance());
89+
90+
Logger rootLogger = Logger.getLogger("");
91+
boolean sessionLoggerAttached = false;
92+
for (Handler handler : rootLogger.getHandlers()) {
93+
sessionLoggerAttached |= handler instanceof PerSessionLogHandler;
94+
}
95+
if (!sessionLoggerAttached) {
96+
rootLogger.addHandler(LoggingManager.perSessionLogHandler());
97+
}
98+
99+
return logger;
100+
}
101+
76102
@Override
77103
protected void service(HttpServletRequest request, HttpServletResponse response)
78104
throws IOException, ServletException {
@@ -165,25 +191,38 @@ public ServletInputStream getInputStream() throws IOException {
165191
private void handle(HttpServletRequest req, HttpServletResponse resp) {
166192
CommandHandler handler = handlers.match(req);
167193

168-
log("Found handler: " + handler);
194+
LOG.info("Found handler: " + handler);
169195

170196
boolean invalidateSession =
171197
handler instanceof ActiveSession &&
172198
"DELETE".equalsIgnoreCase(req.getMethod()) &&
173199
req.getPathInfo().equals("/session/" + ((ActiveSession) handler).getId());
174200

175201
Future<?> execution = executor.submit(() -> {
202+
// Clear the logs
203+
PerSessionLogHandler sessionLogHandler = LoggingManager.perSessionLogHandler();
204+
sessionLogHandler.clearThreadTempLogs();
205+
176206
try {
177207
if (handler instanceof ActiveSession) {
208+
sessionLogHandler .attachToCurrentThread(((ActiveSession) handler).getId());
178209
ActiveSession session = (ActiveSession) handler;
179210
Thread.currentThread().setName(String.format(
180211
"Handler thread for session %s (%s)",
181212
session.getId(),
182213
session.getCapabilities().get(BROWSER_NAME)));
183214
} else {
215+
// All commands that take a session id expect that as the path fragment immediately after "/session".
216+
List<String> fragments = Splitter.on('/').limit(4).splitToList(req.getPathInfo());
217+
if (fragments.size() > 2) {
218+
if ("session".equals(fragments.get(1))) {
219+
sessionLogHandler.attachToCurrentThread(new SessionId(fragments.get(2)));
220+
}
221+
}
222+
184223
Thread.currentThread().setName(req.getPathInfo());
185224
}
186-
log(String.format(
225+
LOG.info(String.format(
187226
"%s: Executing %s on %s (handler: %s)",
188227
Thread.currentThread().getName(),
189228
req.getMethod(),
@@ -197,6 +236,7 @@ private void handle(HttpServletRequest req, HttpServletResponse resp) {
197236
throw new RuntimeException(e);
198237
} finally {
199238
Thread.currentThread().setName("Selenium WebDriver Servlet - Quiescent Thread");
239+
sessionLogHandler.detachFromCurrentThread();
200240
}
201241
});
202242

java/server/src/org/openqa/selenium/remote/server/commandhandler/GetLogTypes.java

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,24 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
118
package org.openqa.selenium.remote.server.commandhandler;
219

320
import static java.net.HttpURLConnection.HTTP_OK;
4-
import static org.openqa.selenium.remote.http.HttpMethod.POST;
21+
import static org.openqa.selenium.remote.http.HttpMethod.GET;
522

623
import com.google.common.collect.ImmutableSet;
724
import com.google.gson.Gson;
@@ -35,7 +52,7 @@ public GetLogTypes(Gson gson, ActiveSession session) {
3552
@Override
3653
public void execute(HttpRequest req, HttpResponse resp) throws IOException {
3754
// Try going upstream first. It's okay if this fails.
38-
HttpRequest upReq = new HttpRequest(POST, String.format("/session/%s/log", session.getId()));
55+
HttpRequest upReq = new HttpRequest(GET, String.format("/session/%s/log/types", session.getId()));
3956
HttpResponse upRes = new HttpResponse();
4057
session.execute(upReq, upRes);
4158

java/server/src/org/openqa/selenium/remote/server/commandhandler/GetLogsOfType.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
package org.openqa.selenium.remote.server.commandhandler;
1919

20+
import static java.nio.charset.StandardCharsets.UTF_8;
21+
import static org.openqa.selenium.remote.http.HttpMethod.POST;
22+
2023
import com.google.gson.Gson;
2124

2225
import org.openqa.selenium.logging.LogEntries;
@@ -44,11 +47,15 @@ public GetLogsOfType(Gson gson, ActiveSession session) {
4447

4548
@Override
4649
public void execute(HttpRequest req, HttpResponse resp) throws IOException {
47-
Map<?, ?> args = gson.fromJson(req.getContentString(), Map.class);
50+
String originalPayload = req.getContentString();
51+
52+
Map<?, ?> args = gson.fromJson(originalPayload, Map.class);
4853
String type = (String) args.get("type");
4954

5055
if (!LogType.SERVER.equals(type)) {
51-
session.execute(req, resp);
56+
HttpRequest upReq = new HttpRequest(POST, String.format("/session/%s/log", session.getId()));
57+
upReq.setContent(originalPayload.getBytes(UTF_8));
58+
session.execute(upReq, resp);
5259
return;
5360
}
5461

0 commit comments

Comments
 (0)