1.发布新包
This commit is contained in:
@@ -108,7 +108,7 @@ public class RetrofitClient {
|
||||
sslContext.init(null, new TrustManager[]{trustAllCert}, new SecureRandom());
|
||||
|
||||
final OkHttpClient client = new OkHttpClient.Builder()
|
||||
// .addInterceptor(new LoggerInterceptor("HttpLog", true))
|
||||
// .addInterceptor(new LogInterceptor())
|
||||
.addInterceptor(new DataLoggingInterceptor(new DataLogger()))
|
||||
.addInterceptor(new AccessTokenInterceptor(headers))
|
||||
.proxy(Proxy.NO_PROXY)
|
||||
|
||||
@@ -867,7 +867,7 @@ public class AgoraManager {
|
||||
VD_360x360,
|
||||
FRAME_RATE_FPS_15,
|
||||
STANDARD_BITRATE,
|
||||
ORIENTATION_MODE_FIXED_PORTRAIT
|
||||
ORIENTATION_MODE_ADAPTIVE
|
||||
));
|
||||
rtcEngine.startScreenCapture(screenCaptureParameters);
|
||||
|
||||
|
||||
@@ -0,0 +1,276 @@
|
||||
package com.xscm.moduleutil.utils.logger;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
import okhttp3.internal.http.HttpHeaders;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
|
||||
/**
|
||||
* OkHttp 日志拦截器,用于打印请求和响应详情
|
||||
*/
|
||||
public class LogInterceptor implements Interceptor {
|
||||
private static final String TAG = "NetworkLog";
|
||||
private static final Charset UTF8 = StandardCharsets.UTF_8;
|
||||
|
||||
// 日志开关(可根据debug/release环境动态设置)
|
||||
private boolean isLogEnabled = true;
|
||||
// 是否打印请求体
|
||||
private boolean logRequestBody = true;
|
||||
// 是否打印响应体
|
||||
|
||||
private boolean logResponseBody = true;
|
||||
// 最大日志长度(避免过大的响应体导致日志刷屏)
|
||||
private int maxLogLength = 2048;
|
||||
|
||||
public LogInterceptor() {
|
||||
}
|
||||
|
||||
// 配置方法
|
||||
public LogInterceptor setLogEnabled(boolean enabled) {
|
||||
isLogEnabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogInterceptor setLogRequestBody(boolean logRequestBody) {
|
||||
this.logRequestBody = logRequestBody;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogInterceptor setLogResponseBody(boolean logResponseBody) {
|
||||
this.logResponseBody = logResponseBody;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LogInterceptor setMaxLogLength(int maxLogLength) {
|
||||
this.maxLogLength = maxLogLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Response intercept(@NonNull Chain chain) throws IOException {
|
||||
if (!isLogEnabled) {
|
||||
return chain.proceed(chain.request());
|
||||
}
|
||||
|
||||
Request request = chain.request();
|
||||
// 打印请求日志
|
||||
logRequest(request);
|
||||
|
||||
// 记录请求开始时间,用于计算耗时
|
||||
long startNs = System.nanoTime();
|
||||
Response response;
|
||||
try {
|
||||
response = chain.proceed(request);
|
||||
} catch (Exception e) {
|
||||
// 打印请求异常
|
||||
Log.e(TAG, "请求失败: " + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
// 计算请求耗时
|
||||
long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
|
||||
|
||||
// 打印响应日志
|
||||
logResponse(response, tookMs);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印请求日志
|
||||
*/
|
||||
private void logRequest(Request request) {
|
||||
try {
|
||||
StringBuilder log = new StringBuilder();
|
||||
log.append("\n==================== 请求开始 ====================\n");
|
||||
|
||||
// 请求行: 方法 + URL
|
||||
log.append(String.format("方法: %s URL: %s\n", request.method(), request.url()));
|
||||
|
||||
// 请求头
|
||||
log.append("请求头:\n");
|
||||
for (String name : request.headers().names()) {
|
||||
// 脱敏敏感头信息(如Authorization、Cookie等)
|
||||
String value = isSensitiveHeader(name) ? "***" : request.headers().get(name);
|
||||
log.append(String.format(" %s: %s\n", name, value));
|
||||
}
|
||||
|
||||
// 请求体
|
||||
if (logRequestBody && request.body() != null) {
|
||||
RequestBody requestBody = request.body();
|
||||
if (requestBody.contentLength() > 0) {
|
||||
log.append("请求体:\n");
|
||||
|
||||
// 复制请求体(避免原请求体被消耗)
|
||||
Buffer buffer = new Buffer();
|
||||
requestBody.writeTo(buffer);
|
||||
Charset charset = UTF8;
|
||||
MediaType contentType = requestBody.contentType();
|
||||
if (contentType != null) {
|
||||
charset = contentType.charset(UTF8);
|
||||
}
|
||||
|
||||
// 读取请求体内容
|
||||
String body = buffer.readString(charset);
|
||||
// 格式化JSON(如果是JSON类型)
|
||||
if (isJson(contentType)) {
|
||||
body = formatJson(body);
|
||||
}
|
||||
// 截断过长的日志
|
||||
log.append(truncateLog(body)).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
log.append("==================== 请求结束 ====================\n");
|
||||
Log.d(TAG, log.toString());
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "打印请求日志失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印响应日志
|
||||
*/
|
||||
private void logResponse(Response response, long tookMs) {
|
||||
try {
|
||||
StringBuilder log = new StringBuilder();
|
||||
log.append("\n==================== 响应开始 ====================\n");
|
||||
|
||||
// 响应行: 状态码 + 消息 + 耗时
|
||||
log.append(String.format("状态码: %d 消息: %s 耗时: %dms\n",
|
||||
response.code(), response.message(), tookMs));
|
||||
|
||||
// 响应头
|
||||
log.append("响应头:\n");
|
||||
for (String name : response.headers().names()) {
|
||||
log.append(String.format(" %s: %s\n", name, response.headers().get(name)));
|
||||
}
|
||||
|
||||
// 响应体
|
||||
if (logResponseBody && HttpHeaders.hasBody(response)) {
|
||||
ResponseBody responseBody = response.body();
|
||||
if (responseBody != null) {
|
||||
BufferedSource source = responseBody.source();
|
||||
source.request(Long.MAX_VALUE); // 读取整个响应体
|
||||
Buffer buffer = source.buffer();
|
||||
|
||||
Charset charset = UTF8;
|
||||
MediaType contentType = responseBody.contentType();
|
||||
if (contentType != null) {
|
||||
charset = contentType.charset(UTF8);
|
||||
}
|
||||
|
||||
// 读取响应体内容
|
||||
String body = buffer.clone().readString(charset);
|
||||
// 格式化JSON
|
||||
if (isJson(contentType)) {
|
||||
body = formatJson(body);
|
||||
}
|
||||
// 截断过长的日志
|
||||
log.append("响应体:\n").append(truncateLog(body)).append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
log.append("==================== 响应结束 ====================\n");
|
||||
Log.d(TAG, log.toString());
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "打印响应日志失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为JSON类型
|
||||
*/
|
||||
private boolean isJson(MediaType mediaType) {
|
||||
if (mediaType == null) return false;
|
||||
return mediaType.type().equals("application") &&
|
||||
mediaType.subtype().equals("json");
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化JSON字符串(增强可读性)
|
||||
*/
|
||||
private String formatJson(String json) {
|
||||
try {
|
||||
// 简单格式化(可根据需要使用更复杂的JSON格式化库)
|
||||
StringBuilder formatted = new StringBuilder();
|
||||
int indent = 0;
|
||||
boolean inQuotes = false;
|
||||
char lastChar = ' ';
|
||||
|
||||
for (char c : json.toCharArray()) {
|
||||
if (c == '"' && lastChar != '\\') {
|
||||
inQuotes = !inQuotes;
|
||||
}
|
||||
|
||||
if (!inQuotes) {
|
||||
switch (c) {
|
||||
case '{':
|
||||
case '[':
|
||||
formatted.append(c).append("\n");
|
||||
indent += 4;
|
||||
formatted.append(" ".repeat(indent));
|
||||
break;
|
||||
case '}':
|
||||
case ']':
|
||||
formatted.append("\n");
|
||||
indent -= 4;
|
||||
formatted.append(" ".repeat(indent)).append(c);
|
||||
break;
|
||||
case ',':
|
||||
formatted.append(c).append("\n").append(" ".repeat(indent));
|
||||
break;
|
||||
case ':':
|
||||
formatted.append(" : ");
|
||||
break;
|
||||
default:
|
||||
formatted.append(c);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
formatted.append(c);
|
||||
}
|
||||
lastChar = c;
|
||||
}
|
||||
return formatted.toString();
|
||||
} catch (Exception e) {
|
||||
// 格式化失败时返回原始字符串
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 截断过长的日志
|
||||
*/
|
||||
private String truncateLog(String log) {
|
||||
if (log.length() <= maxLogLength) {
|
||||
return log;
|
||||
}
|
||||
return log.substring(0, maxLogLength) + "\n...[日志过长,已截断]...";
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为敏感头信息(需要脱敏)
|
||||
*/
|
||||
private boolean isSensitiveHeader(String headerName) {
|
||||
String lowerHeader = headerName.toLowerCase();
|
||||
return lowerHeader.contains("authorization") ||
|
||||
lowerHeader.contains("cookie") ||
|
||||
lowerHeader.contains("token") ||
|
||||
lowerHeader.contains("secret");
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 55 KiB |
Reference in New Issue
Block a user