com.obs.services.internal.utils.OkhttpCallProfiler Maven / Gradle / Ivy
package com.obs.services.internal.utils;
import com.obs.log.ILogger;
import com.obs.log.LoggerBuilder;
import okhttp3.Call;
import okhttp3.Connection;
import okhttp3.EventListener;
import okhttp3.Handshake;
import okhttp3.HttpUrl;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.HashMap;
import java.util.List;
import java.util.function.Consumer;
public class OkhttpCallProfiler extends EventListener {
private final Consumer profiler;
private final HashMap progressStartTime;
private static final ILogger log = LoggerBuilder.getLogger("com.obs.services.ObsClient");
private static final String ProFileTimeUnit = "ms";
static protected boolean isEnabled = true;
public OkhttpCallProfiler(Consumer profiler) {
this.profiler = profiler;
progressStartTime = new HashMap<>();
}
public OkhttpCallProfiler() {
this.profiler = log::debug;
progressStartTime = new HashMap<>();
}
/**
* @param call
*/
@Override
public void callEnd(Call call) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" callEnd ");
appendProgressTime("call", stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param ioe
*/
@Override
public void callFailed(Call call, IOException ioe) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" callFailed ");
appendProgressTime("call", stringBuilder);
appendDetailIOException(ioe, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
*/
@Override
public void callStart(Call call) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" callStart ");
appendProgressTime("call", stringBuilder);
appendDetailForCall(call, stringBuilder, true);
profiler.accept(stringBuilder);
}
/**
* @param call
*/
@Override
public void canceled(Call call) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" call canceled.");
appendProgressTime("call", stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param inetSocketAddress
* @param proxy
* @param protocol
*/
@Override
public void connectEnd(Call call, InetSocketAddress inetSocketAddress, Proxy proxy, Protocol protocol) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" connectEnd ");
appendProgressTime("connect", stringBuilder);
appendDetailInetSocketAddress(inetSocketAddress, stringBuilder);
appendDetailProxy(proxy, stringBuilder);
appendDetailProtocol(protocol, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param inetSocketAddress
* @param proxy
* @param protocol
* @param ioe
*/
@Override
public void connectFailed(
Call call, InetSocketAddress inetSocketAddress, Proxy proxy, Protocol protocol, IOException ioe) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" connectFailed ");
appendProgressTime("connect", stringBuilder);
appendDetailInetSocketAddress(inetSocketAddress, stringBuilder);
appendDetailProxy(proxy, stringBuilder);
appendDetailProtocol(protocol, stringBuilder);
appendDetailIOException(ioe, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param inetSocketAddress
* @param proxy
*/
@Override
public void connectStart(Call call, InetSocketAddress inetSocketAddress, Proxy proxy) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" connectStart ");
appendProgressTime("connect", stringBuilder);
appendDetailInetSocketAddress(inetSocketAddress, stringBuilder);
appendDetailProxy(proxy, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param connection
*/
@Override
public void connectionAcquired(Call call, Connection connection) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" connectionAcquired ");
appendProgressTime("connection", stringBuilder);
appendDetailConnection(connection, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param connection
*/
@Override
public void connectionReleased(Call call, Connection connection) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" connectionReleased ");
appendProgressTime("connection", stringBuilder);
appendDetailConnection(connection, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param domainName
* @param inetAddressList
*/
@Override
public void dnsEnd(Call call, String domainName, List inetAddressList) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" dnsEnd ");
appendProgressTime("dns", stringBuilder);
appendDetailDns(domainName, inetAddressList, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param domainName
*/
@Override
public void dnsStart(Call call, String domainName) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" dnsStart ");
appendProgressTime("dns", stringBuilder);
appendDetailDns(domainName, null, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param url
* @param proxies
*/
@Override
public void proxySelectEnd(Call call, HttpUrl url, List proxies) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" proxySelectEnd ");
appendProgressTime("proxySelect", stringBuilder);
stringBuilder.append(" url{");
stringBuilder.append(url);
stringBuilder.append("} ");
stringBuilder.append(" proxies{");
stringBuilder.append(proxies);
stringBuilder.append("} ");
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param url
*/
@Override
public void proxySelectStart(Call call, HttpUrl url) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" proxySelectStart ");
appendProgressTime("proxySelect", stringBuilder);
stringBuilder.append(" url{");
stringBuilder.append(url);
stringBuilder.append("} ");
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param byteCount
*/
@Override
public void requestBodyEnd(Call call, long byteCount) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" requestBodyEnd ");
appendProgressTime("requestBody", stringBuilder);
appendProgressTime("request", stringBuilder);
stringBuilder.append(" byteCount{");
stringBuilder.append(byteCount);
stringBuilder.append("} ");
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
*/
@Override
public void requestBodyStart(Call call) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" requestBodyStart ");
appendProgressTime("requestBody", stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param ioe
*/
@Override
public void requestFailed(Call call, IOException ioe) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" requestFailed ");
appendProgressTime("request", stringBuilder);
appendDetailIOException(ioe, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param request
*/
@Override
public void requestHeadersEnd(Call call, Request request) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" requestHeadersEnd ");
appendProgressTime("requestHeaders", stringBuilder);
appendDetailRequestHeaders(request, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
*/
@Override
public void requestHeadersStart(Call call) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" requestHeadersStart ");
appendProgressTime("request", stringBuilder);
appendProgressTime("requestHeaders", stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param byteCount
*/
@Override
public void responseBodyEnd(Call call, long byteCount) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" responseBodyEnd ");
appendProgressTime("responseBody", stringBuilder);
appendProgressTime("response", stringBuilder);
stringBuilder.append(" byteCount{");
stringBuilder.append(byteCount);
stringBuilder.append("} ");
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
*/
@Override
public void responseBodyStart(Call call) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" responseBodyStart ");
appendProgressTime("responseBody", stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param ioe
*/
@Override
public void responseFailed(Call call, IOException ioe) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" responseFailed ");
appendProgressTime("response", stringBuilder);
appendDetailIOException(ioe, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param response
*/
@Override
public void responseHeadersEnd(Call call, Response response) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" responseHeadersEnd ");
appendProgressTime("responseHeaders", stringBuilder);
appendDetailResponseHeaders(response, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
*/
@Override
public void responseHeadersStart(Call call) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" responseHeadersStart ");
appendProgressTime("response", stringBuilder);
appendProgressTime("responseHeaders", stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
* @param handshake
*/
@Override
public void secureConnectEnd(Call call, Handshake handshake) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" secureConnectEnd ");
appendProgressTime("secureConnect", stringBuilder);
appendDetailHandshake(handshake, stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
/**
* @param call
*/
@Override
public void secureConnectStart(Call call) {
if (!isEnabled) {
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(" secureConnectStart ");
appendProgressTime("secureConnect", stringBuilder);
appendDetailForCall(call, stringBuilder);
profiler.accept(stringBuilder);
}
protected void appendProgressTime(String progressName, StringBuilder stringBuilder) {
Long startTime = this.progressStartTime.get(progressName);
if (startTime == null) {
startTime = System.currentTimeMillis();
this.progressStartTime.put(progressName, startTime);
stringBuilder.append(progressName);
stringBuilder.append(" start time: ");
stringBuilder.append(startTime);
stringBuilder.append(ProFileTimeUnit);
stringBuilder.append(" ");
} else {
long currentTime = System.currentTimeMillis();
long costTime = currentTime - startTime;
this.progressStartTime.remove(progressName, startTime);
stringBuilder.append(progressName);
stringBuilder.append(" cost time: ");
stringBuilder.append(costTime);
stringBuilder.append(ProFileTimeUnit);
stringBuilder.append(" end time: ");
stringBuilder.append(currentTime);
stringBuilder.append(ProFileTimeUnit);
stringBuilder.append(" ");
}
}
protected void appendDetailForCall(Call call, StringBuilder stringBuilder) {
appendDetailForCall(call, stringBuilder, false);
}
protected void appendDetailForCall(Call call, StringBuilder stringBuilder, boolean needDetail) {
stringBuilder.append("call {");
if (needDetail) {
stringBuilder.append("url:");
stringBuilder.append(call.request().url());
stringBuilder.append(" method:");
stringBuilder.append(call.request().method());
stringBuilder.append(" ");
}
stringBuilder.append("hash:");
stringBuilder.append(System.identityHashCode(call));
stringBuilder.append("} ");
}
protected void appendDetailInetSocketAddress(InetSocketAddress inetSocketAddress, StringBuilder stringBuilder) {
stringBuilder.append(" InetSocketAddress {");
stringBuilder.append(inetSocketAddress);
stringBuilder.append("} ");
}
protected void appendDetailProxy(Proxy proxy, StringBuilder stringBuilder) {
stringBuilder.append(" Proxy {type:");
stringBuilder.append(proxy.type());
stringBuilder.append(" address:");
stringBuilder.append(proxy.address());
stringBuilder.append("} ");
}
protected void appendDetailProtocol(Protocol protocol, StringBuilder stringBuilder) {
stringBuilder.append(" Protocol{");
stringBuilder.append(protocol);
stringBuilder.append("} ");
}
protected void appendDetailConnection(Connection connection, StringBuilder stringBuilder) {
stringBuilder.append(" ");
stringBuilder.append(connection);
stringBuilder.append(" ");
}
protected void appendDetailDns(String domainName, List inetAddressList, StringBuilder stringBuilder) {
stringBuilder.append(" domainName:");
stringBuilder.append(domainName);
stringBuilder.append(" inetAddressList{");
stringBuilder.append(inetAddressList);
stringBuilder.append("} ");
}
protected void appendDetailRequestHeaders(Request request, StringBuilder stringBuilder) {
stringBuilder.append(" requestHeaders{");
stringBuilder.append(request.headers());
stringBuilder.append("} ");
}
protected void appendDetailResponseHeaders(Response response, StringBuilder stringBuilder) {
stringBuilder.append(" responseHeaders{");
stringBuilder.append(response.headers());
stringBuilder.append("} ");
}
protected void appendDetailHandshake(Handshake handshake, StringBuilder stringBuilder) {
stringBuilder.append(" handshake{");
stringBuilder.append(handshake);
stringBuilder.append("} ");
}
protected void appendDetailIOException(IOException ioe, StringBuilder stringBuilder) {
try (StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter)) {
ioe.printStackTrace(printWriter);
stringBuilder.append(stringWriter);
} catch (IOException ignore) {
stringBuilder.append("appendDetailIOException failed");
}
}
public static boolean isEnabled() {
return isEnabled;
}
public static void setEnabled(boolean enabled) {
isEnabled = enabled;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy