# 📡 Capture Your Mobile Application’s Network Logs from Automation – Part 2

## **🔄 Recap: What We Did in Part 1?**

[In **P**](#)[**art 1**](#), we successfully set [up **MIT**](#)**M Proxy** to intercept network requests from a mobile app running on an **Android/iOS device**. We learned how to:

✅ Install **MITM Proxy** and start [a **prox**](#)**y server**.  
✅ Configure **proxy settings** on a real device/emulator.  
✅ Intercept **HTTP & HTTPS requests** using a **MITM CA Certificate**.

🚀 **That was fun, but now let’s** [**take i**](#)**t to the next level!**

### **🔥 What’s Next?**

We don’t just [want t](#)o **view netw**[**ork lo**](#)**gs**—we want to **capture them programmatically** in our **automation framework**.

And for that, we’ll use **MITM Pr**[**oxy’s**](#) **Java Client**!

---

### **🤖 What is the MITM Proxy Java Client?**

The **MITM Proxy Java Client** ([mitmproxy-ja](https://github.com/appium/mitmproxy-java)[va) acts as a](https://github.com/appium/mitmproxy-java) **bridge** between **MITM Proxy** [and your Java-](https://github.com/appium/mitmproxy-java)based automation framework.

💡 Here’s how it works:

✅ **MITM Proxy** starts a **WebSocket server**.  
✅ A **Python plug**[**in** inside MITM](https://github.com/appium/mitmproxy-java) Proxy send[s network traf](https://github.com/appium/mitmproxy-java)fic **to the Java client**.  
✅ The **Java client captures and stores network requests** for analysis.

With this setup, we can:  
🔍 Capture **API calls** made by the mobile app.  
📄 Save ne[twork logs **for**](https://github.com/appium/mitmproxy-java) **debugging**.  
🔗 Attach logs **to test reports**.

# **⚙️ Step 1: Install the Required Dependencies**

### **📌 Prerequisites**

Before setting up the Java client, make sure you have:

1️⃣ **MITM Proxy v9+** installed and working.  
2️⃣ **Python 3.6+** (MITM Proxy uses async WebSockets).  
3️⃣ **WebSockets module** installed:

```bash
pip3 install websockets
```

### **📌 Add MITM Proxy Java Dependency to Your Project**

If you’re using **Maven**, add this dependency to your `pom.xml`:

```xml
<dependency>
  <groupId>io.appium</groupId>
  <artifactId>mitmproxy-java</artifactId>
  <version>2.0.2</version>
</dependency>
```

🚨 **Note:** The latest version **is not yet available in the official repository**, so you may need to **clone the source code and build your own JAR**.  

### **📂 Step 2: Integrate MITM Proxy Java Client in Your Framework**

## **🕒 Step 2.1: Create a Class to Store Intercepted Messages**

To store network logs **with timestamps**, create [`InterceptedMessages.java`](http://InterceptedMessages.java):

```java
import io.appium.mitmproxy.InterceptedMessage;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

import java.util.Date;

/**
 * Stores intercepted message along with timestamp.
 */
public class InterceptedMessages {
    @Accessors(chain = true)
    @Getter@Setter
    private Date timestamp;

    @Accessors(chain = true)
    @Getter@Setter
    private InterceptedMessage interceptedMessage;
}
```

🚀 **Now every intercepted request will be saved with a timestamp!**

---

## **🛠 Step 2.2: Add a Handler to Start & Stop MITM Proxy**

Now, let’s create [`MITMProxy.java`](http://MITMProxy.java) to:  
✅ Start the **proxy listener**.  
✅ Capture **network traffic**.  
✅ Stop the **proxy** when needed.

```java
import io.appium.mitmproxy.InterceptedMessage;
import io.appium.mitmproxy.MitmproxyJava;
import lombok.Getter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeoutException;

/**
 * MITM Proxy Utility for Capturing Network Logs in Automation Framework.
 */
public class MITMProxy {
    @Getter
    private final List<InterceptedMessages> networkCalls = new ArrayList<>();

    private static MITMProxy proxyInstance = null;
    private MitmproxyJava proxy;

    // Singleton Pattern to Ensure Single Instance
    private MITMProxy() {
        startProxyListener();
    }

    public static MITMProxy getProxy() {
        if (proxyInstance == null)
            proxyInstance = new MITMProxy();
        return proxyInstance;
    }

    /**
     * Starts MITM Proxy and Listens for Network Traffic
     */
    private void startProxyListener() {
        System.out.println("🚀 Starting MITM Proxy Listener...");

        List<String> extraMitmproxyParams = Arrays.asList("--showhost", "<domain-name-filter>");
        int mitmproxyPort = 8090;

        this.proxy = new MitmproxyJava(getMitmDumpPath(), (InterceptedMessage message) -> {
            InterceptedMessages interceptedMessage = new InterceptedMessages()
                    .setTimestamp(new Date())
                    .setInterceptedMessage(message);
            networkCalls.add(interceptedMessage);
            
            // Log each intercepted message
            System.out.println("🔍 Captured Network Request at: " + interceptedMessage.getTimestamp());
            System.out.println("📡 Request Details: " + message);
            
            return message;
        }, mitmproxyPort, extraMitmproxyParams);

        try {
            // Kill existing process on the same port if running
            String processId = ProcessExecutor.executeCommandSync("lsof -t -i:" + mitmproxyPort + " -sTCP:LISTEN").trim();
            if (!processId.isEmpty())
                ProcessExecutor.executeCommandSync("kill -9 " + processId);

            this.proxy.start();
        } catch (IOException | TimeoutException e) {
            throw new RuntimeException("❌ Failed to Start Proxy: " + e.getMessage());
        }

        System.out.println("✅ Proxy Listener Started Successfully!");
    }

    /**
     * Retrieves MITM Dump Path
     */
    private String getMitmDumpPath() {
        String result = ProcessExecutor.executeCommandSync("whereis mitmdump");
        return result.split("mitmdump: ")[1].split(" ")[0].trim();
    }

    /**
     * Stops MITM Proxy
     */
    public void stopProxyListener() {
        System.out.println("🛑 Stopping MITM Proxy Listener...");
        try {
            this.proxy.stop();
        } catch (InterruptedException e) {
            throw new RuntimeException("❌ Failed to Stop Proxy: " + e.getMessage());
        }
        System.out.println("✅ Proxy Listener Stopped Successfully!");
    }

    /**
     * Prints All Captured Network Logs
     */
    public void printCapturedLogs() {
        System.out.println("📜 Printing Captured Network Logs...");
        
        if (networkCalls.isEmpty()) {
            System.out.println("⚠️ No network requests were intercepted.");
            return;
        }

        for (InterceptedMessages msg : networkCalls) {
            System.out.println("⏳ Captured Request at: " + msg.getTimestamp());
            System.out.println("📡 Request Details: " + msg.getInterceptedMessage());
            System.out.println("--------------------------------------------------");
        }
    }
}
```

### **🔥 What Does This Class Do?**

✅ **Automatically starts MITM Proxy** when called.  
✅ **Captures every intercepted request** and stores it with a timestamp.  
✅ **Prevents port conflicts** by killing any existing process on the same port.

---

# **🚀 Step 3: Start Capturing Network Logs**

### **🎬 Start the Proxy**

```java
MITMProxy.getProxy();
```

👉 This **starts the MITM Proxy** and begins capturing **network requests**.

---

### **📄 Fetch Intercepted Logs**

```java
networkLogMessage = MITMProxy.getProxy().getNetworkCalls();
```

👉 This **retrieves all captured network logs**, which can be saved or attached to reports.

---

### **🛑 Stop the Proxy**

```java
MITMProxy.getProxy().stopProxyListener();
```

👉 This **stops the proxy** when tests are complete.

---

# **🔍 Verifying Captured Logs**

Once your tests have run, print the **captured logs** to verify that requests are being intercepted:

```java
for (InterceptedMessages msg : MITMProxy.getProxy().getNetworkCalls()) {
    System.out.println("Captured Request at: " + msg.getTimestamp());
    System.out.println("Request Details: " + msg.getInterceptedMessage());
}
```

🎉 **Now you can capture and analyze every network request in your tests!**

---

# **🎯 What’s Next?**

✅ **We can now intercept API calls from our mobile automation framework!** 🎯

**But what if we need to store these logs for later analysis?** 🤔

👉 In **Part 3**, we’ll:  
✅ **Save network logs to files** for debugging.  
✅ **Attach logs to automation test reports**.  
✅ **Filter out unwanted noise** from logs.

**Stay tuned for Part 3! 🚀🔥**

💬 **Questions? Drop a comment below!**
