package com.debug.mcp;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
/**
* Debug HTTP Client for MCP Debug Server
*
* This utility class sends debug logs to the MCP debug server via HTTP POST.
* It handles JSON serialization and error handling silently to not interrupt main logic.
*
* Usage:
* DebugHttpClient.sendLog("http://localhost:3000/api/log", "Debug message", variables, "info");
*
* Note: In Android environments, network requests must be executed in a background thread.
* This class does NOT handle threading - the caller must ensure proper thread management.
*/
public class DebugHttpClient {
private static final int CONNECT_TIMEOUT_MS = 100;
private static final int READ_TIMEOUT_MS = 100;
/**
* Send debug log to MCP debug server
*
* @param serverUrl The debug server URL (e.g., "http://localhost:3000/api/log")
* @param logMessage The debug message
* @param variables Variable values to log (can be null or empty)
* @param level Log level: "info", "error", "debug", "warn"
*/
public static void sendLog(String serverUrl, String logMessage, Object variables, String level) {
try {
URL url = new URL(serverUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// Configure connection
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setConnectTimeout(CONNECT_TIMEOUT_MS);
conn.setReadTimeout(READ_TIMEOUT_MS);
conn.setDoOutput(true);
// Build JSON payload
String jsonPayload = buildJsonPayload(logMessage, variables, level);
// Send request
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonPayload.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
// Read response (ignore result, just ensure connection completes)
int responseCode = conn.getResponseCode();
// Silently ignore response - we don't want to break main logic
conn.disconnect();
} catch (Exception e) {
// Silent fail - do not throw exceptions or log to console
// This ensures debug logging never interrupts main application flow
}
}
/**
* Build JSON payload for debug log
*/
private static String buildJsonPayload(String logMessage, Object variables, String level) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String timestamp = sdf.format(new Date());
StringBuilder json = new StringBuilder();
json.append("{");
json.append("\"timestamp\":\"").append(timestamp).append("\",");
json.append("\"level\":\"").append(level != null ? level : "info").append("\",");
json.append("\"message\":\"").append(escapeJson(logMessage)).append("\",");
json.append("\"data\":");
if (variables != null) {
json.append(variables.toString());
} else {
json.append("{}");
}
json.append("}");
return json.toString();
}
/**
* Escape JSON string
*/
private static String escapeJson(String str) {
if (str == null) {
return "";
}
return str.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r")
.replace("\t", "\\t");
}
}