QQBot/src/main/java/com/yutou/okhttp/HttpLoggingInterceptor.java
Yutou bc378a5c59 feat(gpt): 优化临时消息处理逻辑
- 修改 clear 方法,移除同步关键字
- 优化 sendTmpMessage 方法,增加日志记录和处理流程
- 更新 GetSeTu 类,改进擦边图片请求的回复文案
-调整 HttpLoggingInterceptor,启用日志输出
- 更新 QQBotApplication 版本号至 1.7.21
2025-02-28 18:07:09 +08:00

217 lines
7.8 KiB
Java

package com.yutou.okhttp;
import com.yutou.qqbot.utlis.Log;
import lombok.val;
import okhttp3.*;
import okhttp3.internal.http.HttpHeaders;
import okio.Buffer;
import okio.BufferedSource;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
public class HttpLoggingInterceptor implements Interceptor {
private static final String TAG = "HttpLogging";
private static final Charset UTF8 = StandardCharsets.UTF_8;
private volatile Level printLevel = Level.BODY;
private java.util.logging.Level colorLevel;
private Logger logger;
private static boolean prLog;
public static void setLog(boolean log) {
prLog = log;
}
public enum Level {
NONE, //不打印log
BASIC, //只打印 请求首行 和 响应首行
HEADERS, //打印请求和响应的所有 Header
BODY //所有数据全部打印
}
public HttpLoggingInterceptor(String tag) {
logger = Logger.getLogger(tag);
colorLevel = java.util.logging.Level.INFO;
}
public void setPrintLevel(Level level) {
if (printLevel == null)
throw new NullPointerException("printLevel == null. Use Level.NONE instead.");
printLevel = level;
}
public void setColorLevel(java.util.logging.Level level) {
colorLevel = level;
}
private void log(String message) {
//logger.log(colorLevel, message);
if (prLog) {
// Log.getDynamicLogger(TAG).info(message);
System.out.println(message);
}
//Log.e(TAG,message);
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (request.body() != null && request.body().contentLength() == 0) {
val headers = request.headers();
request = chain.call().request().newBuilder()
.headers(headers)
.build();
}
if (printLevel == Level.NONE) {
return chain.proceed(request);
}
//请求日志拦截
logForRequest(request, chain.connection());
//执行请求,计算请求时间
long startNs = System.nanoTime();
Response response;
try {
response = chain.proceed(request);
} catch (Exception e) {
log("<-- HTTP FAILED: " + e);
throw e;
}
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
//响应日志拦截
return logForResponse(response, tookMs);
}
private void logForRequest(Request request, Connection connection) throws IOException {
boolean logBody = (printLevel == Level.BODY);
boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
RequestBody requestBody = request.body();
boolean hasRequestBody = requestBody != null;
Protocol protocol = connection != null ? connection.protocol() : Protocol.HTTP_1_1;
try {
String requestStartMessage = "--> " + request.method() + ' ' + request.url() + ' ' + protocol;
log(requestStartMessage);
if (logHeaders) {
if (hasRequestBody) {
if (requestBody.contentType() != null) {
log("\tContent-Type: " + requestBody.contentType());
}
if (requestBody.contentLength() != -1) {
log("\tContent-Length: " + requestBody.contentLength());
}
}
Headers headers = request.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
String name = headers.name(i);
if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
log("\t" + name + ": " + headers.value(i));
}
}
log(" ");
if (logBody && hasRequestBody) {
if (isPlaintext(requestBody.contentType())) {
bodyToString(request);
} else {
log("\tbody: maybe [binary body], omitted!");
}
}
}
} catch (Exception e) {
logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
} finally {
log("--> END " + request.method());
}
}
private Response logForResponse(Response response, long tookMs) {
Response.Builder builder = response.newBuilder();
Response clone = builder.build();
ResponseBody responseBody = clone.body();
boolean logBody = (printLevel == Level.BODY);
boolean logHeaders = (printLevel == Level.BODY || printLevel == Level.HEADERS);
try {
log("<-- " + clone.code() + ' ' + clone.message() + ' ' + clone.request().url() + " (" + tookMs + "ms)");
if (logHeaders) {
Headers headers = clone.headers();
for (int i = 0, count = headers.size(); i < count; i++) {
log("\t" + headers.name(i) + ": " + headers.value(i));
}
log(" ");
if (logBody && HttpHeaders.hasBody(clone)) {
if (responseBody == null) return response;
if (isPlaintext(responseBody.contentType())) {
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // 请求整个流
Buffer buffer = source.buffer();
Charset charset = getCharset(responseBody.contentType());
String body = buffer.clone().readString(charset);
log("\tbody:" + body);
} else {
log("\tbody: maybe [binary body], omitted!");
}
}
}
} catch (Exception e) {
logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
} finally {
log("<-- END HTTP");
}
return response;
}
private static Charset getCharset(MediaType contentType) {
Charset charset = contentType != null ? contentType.charset(UTF8) : UTF8;
if (charset == null) charset = UTF8;
return charset;
}
/**
* Returns true if the body in question probably contains human readable text. Uses a small sample
* of code points to detect unicode control characters commonly used in binary file signatures.
*/
private static boolean isPlaintext(MediaType mediaType) {
if (mediaType == null) return false;
if (mediaType.type() != null && mediaType.type().equals("text")) {
return true;
}
String subtype = mediaType.subtype();
if (subtype != null) {
subtype = subtype.toLowerCase();
if (subtype.contains("x-www-form-urlencoded") || subtype.contains("json") || subtype.contains("xml") || subtype.contains("html")) //
return true;
}
return false;
}
private void bodyToString(Request request) {
try {
Request copy = request.newBuilder().build();
RequestBody body = copy.body();
if (body == null) return;
Buffer buffer = new Buffer();
body.writeTo(buffer);
Charset charset = getCharset(body.contentType());
log("\tbody:" + buffer.readString(charset));
// 重置请求体以确保后续处理不受影响
buffer.clear();
} catch (Exception e) {
logger.log(java.util.logging.Level.WARNING, e.getMessage(), e);
}
}
}