Tuesday, October 6, 2026

Network Log Capture

 import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v154.network.Network;
import org.openqa.selenium.devtools.v154.network.model.RequestId;

public class NetworkLogCapture {
    public static Logger APP_LOGS = LogManager.getLogger(NetworkLogCapture.class.getName());

    private DevTools devTools;
    private final List<String> failedRequests = new ArrayList<>();

    public void enableNetworkLogging(ChromeDriver driver) {
        devTools = driver.getDevTools();
        devTools.createSession();
        // Store URL per requestId for correlation
        Map<String, String> requestUrlMap = new ConcurrentHashMap<>();

        // Enable Network domain
        devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(),
                Optional.empty()));

        // Log all requests
        devTools.addListener(Network.requestWillBeSent(), request -> {
            String url = request.getRequest().getUrl();
            requestUrlMap.put(request.getRequestId().toString(), url);
            APP_LOGS.info("\n=== REQUEST ===");
            APP_LOGS.info("URL     : " + url);
            APP_LOGS.info("Method  : " + request.getRequest().getMethod());
            APP_LOGS.info("Headers : " + request.getRequest().getHeaders());
            // Request body (only for POST/PUT)
            request.getRequest().getPostDataEntries().ifPresent(b -> APP_LOGS.info("REQUEST BODY   : " + b));
            // Fetch post data via CDP if not inline
            try {
                RequestId requestId = request.getRequestId();
                String postData = devTools.send(Network.getRequestPostData(requestId)).getPostData();
                APP_LOGS.info("[REQUEST BODY - CDP] " + postData);
            } catch (Exception e) {
                APP_LOGS.info("[REQUEST BODY] Not available: " + e.getMessage());
            }
        });

        // Log all responses
        devTools.addListener(Network.responseReceived(), response -> {
            int status = response.getResponse().getStatus();
            String url = response.getResponse().getUrl();

            // Flag non-2xx responses (blocked, failed, etc.)
            if (status >= 400 || status == 0) {
                failedRequests.add(status + " | " + url);
                APP_LOGS.info("\n=== RESPONSE HEADERS ===");
                APP_LOGS.info("Status  : " + status);
                APP_LOGS.info("URL     : " + url);
                APP_LOGS.info("Headers : " + response.getResponse().getHeaders());
            }
        });

        // Log load failures (blocked by firewall/CSP)
        devTools.addListener(Network.loadingFinished(), finished -> {
            String url = requestUrlMap.getOrDefault(finished.getRequestId().toString(), "");
            try {
                Network.GetResponseBodyResponse body = devTools.send(Network.getResponseBody(finished.getRequestId()));

                APP_LOGS.info("\n=== RESPONSE BODY (" + url + ") ===");
                APP_LOGS.info(body.getBase64Encoded() ? new String(java.util.Base64.getDecoder().decode(body.getBody()))
                        : body.getBody());
            } catch (Exception e) {
                APP_LOGS.info("[RESPONSE BODY] Skipped: " + e.getMessage());
            }
        });

        // Log load failures (blocked by firewall/CSP)
        devTools.addListener(Network.loadingFailed(), failed -> {
            APP_LOGS.error("[FAILED] " + failed.getErrorText() + " | blocked=" + failed.getBlockedReason()
                    + " | url type=" + failed.getType());
        });
    }

    public void printFailedRequests() {
        APP_LOGS.info("=== FAILED/BLOCKED REQUESTS ===");
        failedRequests.forEach(msg -> APP_LOGS.error(msg));
    }
}

No comments:

Post a Comment