Skip to content

Commit 845f455

Browse files
author
BitsAdmin
committed
Merge branch 'feature/yg/meego-6739737753-add-debugger' into 'integration_2025-09-25_1060179278594'
feat: [development task] core (1697924) See merge request iaasng/volcengine-java-sdk!681
2 parents ea10250 + bfd421e commit 845f455

File tree

16 files changed

+932
-38
lines changed

16 files changed

+932
-38
lines changed

SDK_Integration_zh.md

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
- [退避策略](#退避策略)
3333
- [异常处理](#异常处理)
3434
- [Debug机制](#debug机制)
35+
- [开启Debug模式](#开启debug模式)
3536

3637
# 集成SDK
3738

@@ -641,23 +642,17 @@ public class SampleCode {
641642

642643
为便于客户在处理请求时进行问题排查和调试,SDK 支持日志功能,并提供多种日志级别设置。客户可根据实际需求配置日志级别,获取详细的请求与响应信息,以提升排障效率和系统可 observability(可观测性)。
643644

645+
## 开启Debug模式
646+
644647
> **默认**
645-
> * `debugging` - `false` (表示不开启debug模式)
648+
> * `debug` - `false` (表示不开启debug模式)
646649
647-
Java SDK使用的是`com.squareup.okhttp.OkHttpClient`,可以通过设置`debugging`来开启debug模式
650+
Java SDK日志使用的是slf4j,需要依赖客户的配置文件,客户可以根据自己的需求,配置日志级别
648651

649-
```java
650-
import com.volcengine.ApiClient;
651-
import com.volcengine.sign.Credentials;
652-
653-
public class SampleCode {
654-
public static void main(String[] args) {
655-
String regionId = "cn-beijing";
656-
ApiClient apiClient = new ApiClient()
657-
.setCredentials(Credentials.getEnvCredentials())
658-
.setRegion(regionId)
659-
.setDebugging(true);
660-
}
661-
}
652+
**配置示例:**
662653

654+
```xml
655+
<!--开启debug日志-->
656+
<logger name="com.volcengine.sdkcore" level="debug"/>
663657
```
658+

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<common-lang-version>2.6</common-lang-version>
4444
<javax.annotation-version>1.3.2</javax.annotation-version>
4545
<javax.validation-version>2.0.1.Final</javax.validation-version>
46+
<org.slf4j.version>1.7.36</org.slf4j.version>
4647
</properties>
4748
<dependencyManagement>
4849
<dependencies>
@@ -91,6 +92,12 @@
9192
<artifactId>validation-api</artifactId>
9293
<version>${javax.validation-version}</version>
9394
</dependency>
95+
<!-- SDK 中提供日志接口 -->
96+
<dependency>
97+
<groupId>org.slf4j</groupId>
98+
<artifactId>slf4j-api</artifactId>
99+
<version>${org.slf4j.version}</version>
100+
</dependency>
94101
</dependencies>
95102
</dependencyManagement>
96103
<profiles>

volcengine-java-sdk-core/pom.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
<version>0.2.36</version>
77
<relativePath>../pom.xml</relativePath>
88
</parent>
9+
<build>
10+
<plugins>
11+
<plugin>
12+
<groupId>org.apache.maven.plugins</groupId>
13+
<artifactId>maven-compiler-plugin</artifactId>
14+
<configuration>
15+
<source>8</source>
16+
<target>8</target>
17+
</configuration>
18+
</plugin>
19+
</plugins>
20+
</build>
921
<modelVersion>4.0.0</modelVersion>
1022
<artifactId>volcengine-java-sdk-core</artifactId>
1123
<name>volcengine-java-sdk-core</name>
@@ -48,5 +60,10 @@
4860
<artifactId>javax.annotation-api</artifactId>
4961
<scope>compile</scope>
5062
</dependency>
63+
<!-- SDK 中提供日志接口 -->
64+
<dependency>
65+
<groupId>org.slf4j</groupId>
66+
<artifactId>slf4j-api</artifactId>
67+
</dependency>
5168
</dependencies>
5269
</project>

volcengine-java-sdk-core/src/main/java/com/volcengine/ApiClient.java

Lines changed: 85 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@
2727
import com.squareup.okhttp.Response;
2828
import com.squareup.okhttp.internal.http.HttpMethod;
2929
import com.squareup.okhttp.logging.HttpLoggingInterceptor;
30-
import com.squareup.okhttp.logging.HttpLoggingInterceptor.Level;
3130
import com.volcengine.auth.Authentication;
3231
import com.volcengine.auth.CredentialProvider;
32+
import com.volcengine.observability.debugger.LogLevel;
33+
import com.volcengine.observability.debugger.SdkConfigLog;
3334
import com.volcengine.endpoint.DefaultEndpointProvider;
3435
import com.volcengine.endpoint.EndpointResolver;
3536
import com.volcengine.interceptor.BuildRequestInterceptor;
@@ -42,6 +43,7 @@
4243
import com.volcengine.interceptor.SignRequestInterceptor;
4344
import com.volcengine.model.AbstractResponse;
4445
import com.volcengine.model.ResponseMetadata;
46+
import com.volcengine.observability.debugger.SdkDebugLog;
4547
import com.volcengine.retryer.BackoffStrategy;
4648
import com.volcengine.retryer.DefaultRetryerSetting;
4749
import com.volcengine.retryer.RetryCondition;
@@ -97,6 +99,9 @@
9799
import java.util.regex.Matcher;
98100
import java.util.regex.Pattern;
99101

102+
import static com.volcengine.observability.debugger.LogLevel.LOG_DEBUG_WITH_CONFIG;
103+
import static com.volcengine.observability.debugger.SdkDebugLog.SDK_CORE_LOGGER;
104+
100105
public class ApiClient extends BaseClient{
101106
private final static String DefaultAuthentication = "volcengineSign";
102107

@@ -144,6 +149,7 @@ public class ApiClient extends BaseClient{
144149

145150
private String httpProxy;
146151
private String httpsProxy;
152+
private SdkConfigLog sdkConfigLog;
147153

148154
/*
149155
* Constructor for ApiClient
@@ -152,6 +158,7 @@ public ApiClient() {
152158
ConnectionPool connectionPool = new ConnectionPool(maxIdleConns, keepAliveDurationMs);
153159
httpClient = new OkHttpClient();
154160
httpClient.setConnectionPool(connectionPool);
161+
httpClient.interceptors().add(new com.volcengine.interceptor.HttpLoggingInterceptor());
155162
verifyingSsl = true;
156163

157164
json = new JSON();
@@ -464,21 +471,11 @@ public boolean isDebugging() {
464471

465472
/**
466473
* Enable/disable debugging for this API client.
467-
*
474+
* @Deprecated
468475
* @param debugging To enable (true) or disable (false) debugging
469476
* @return ApiClient
470477
*/
471478
public ApiClient setDebugging(boolean debugging) {
472-
if (debugging != this.debugging) {
473-
if (debugging) {
474-
loggingInterceptor = new HttpLoggingInterceptor();
475-
loggingInterceptor.setLevel(Level.BODY);
476-
httpClient.interceptors().add(loggingInterceptor);
477-
} else {
478-
httpClient.interceptors().remove(loggingInterceptor);
479-
loggingInterceptor = null;
480-
}
481-
}
482479
this.debugging = debugging;
483480
return this;
484481
}
@@ -1091,6 +1088,7 @@ public <T> ApiResponse<T> execute(Call call, final Type returnType, boolean... i
10911088
responseInterceptorContext.setReturnType(returnType);
10921089
context.setResponseContext(responseInterceptorContext);
10931090
context.setApiClient(this);
1091+
logSdkConfig();
10941092

10951093
int numMaxRetries = retryer.getNumMaxRetries();
10961094
ApiException apiException;
@@ -1144,10 +1142,12 @@ private ApiException handleApiResponseException(ApiException apiException) {
11441142

11451143
private boolean requestShouldRetry(ApiResponse apiResponse, int retryCount, ApiException lastException) throws ApiException {
11461144
if (autoRetry && retryer.shouldRetry(apiResponse, retryCount, lastException)) {
1145+
SDK_CORE_LOGGER.debugRetry("maxReryCout:{}, currentRetryCount:{}, backoffStrategy:{}", retryer.getNumMaxRetries(), retryCount + 1, retryer.getBackoffStrategy().getClass().getSimpleName());
11471146
try {
11481147
long delay = retryer.getBackoffDelay(retryCount);
11491148
Thread.sleep(delay);
11501149
} catch (Exception e) {
1150+
SDK_CORE_LOGGER.error(()->"Failed to getBackoffDelay or sleep", e);
11511151
throw new ApiException(e);
11521152
}
11531153
return true;
@@ -1188,6 +1188,7 @@ public <T> void executeAsync(Call call, final Type returnType, final ApiCallback
11881188
context.setResponseContext(responseInterceptorContext);
11891189

11901190
context.setApiClient(this);
1191+
logSdkConfig();
11911192

11921193
final int maxRetries = retryer.getNumMaxRetries();
11931194
final AtomicInteger retryCount = new AtomicInteger(0);
@@ -2008,4 +2009,76 @@ public ApiClient setBackoffStrategy(BackoffStrategy backoffStrategy) throws ApiE
20082009
public OkHttpClient getOkHttpClient() {
20092010
return this.httpClient;
20102011
}
2012+
2013+
/**
2014+
* 设置日志级别。
2015+
*
2016+
* <p>logLevel 的值应来自 {@link LogLevel} 枚举的 {@link LogLevel#mask()},
2017+
* 可以通过 {@link LogLevel#combine(LogLevel...)} 组合多个模式。</p>
2018+
*
2019+
* <p>常见用法示例:</p>
2020+
* <pre>{@code
2021+
* // 只启用请求日志
2022+
* logger.setLogLevel(LogLevel.LOG_DEBUG_WITH_REQUEST.mask());
2023+
*
2024+
* // 启用请求和响应日志
2025+
* logger.setLogLevel(LogLevel.combine(
2026+
* LogLevel.LOG_DEBUG_WITH_REQUEST,
2027+
* LogLevel.LOG_DEBUG_WITH_RESPONSE));
2028+
*
2029+
* // 启用所有调试日志
2030+
* logger.setLogLevel(LogLevel.LOG_DEBUG_ALL.mask());
2031+
* }</pre>
2032+
*
2033+
* @param logLevel 日志级别标志位,参考 {@link LogLevel}
2034+
*/
2035+
public ApiClient setLogLevel(long logLevel) {
2036+
SdkDebugLog.SDK_CORE_LOGGER.setLogLevel(logLevel);
2037+
return this;
2038+
}
2039+
2040+
public long getLogLevel() {
2041+
return SdkDebugLog.SDK_CORE_LOGGER.getLogLevel();
2042+
}
2043+
2044+
private void logSdkConfig() {
2045+
if (!SDK_CORE_LOGGER.isDebugEnabled() || !SDK_CORE_LOGGER.matches(LOG_DEBUG_WITH_CONFIG)){
2046+
return;
2047+
}
2048+
2049+
if (this.sdkConfigLog != null) {
2050+
this.sdkConfigLog.log();
2051+
}
2052+
synchronized (this){
2053+
2054+
if (this.sdkConfigLog != null) {
2055+
this.sdkConfigLog.log();
2056+
}
2057+
2058+
SdkConfigLog sdkConfigLog = new SdkConfigLog();
2059+
sdkConfigLog.setMaxIdleConns(this.maxIdleConns);
2060+
sdkConfigLog.setKeepAliveDurationMs(this.keepAliveDurationMs);
2061+
sdkConfigLog.setDisableSSL(this.disableSSL);
2062+
sdkConfigLog.setVerifyingSsl(this.verifyingSsl);
2063+
sdkConfigLog.setHttpProxy(this.httpProxy);
2064+
sdkConfigLog.setHttpsProxy(this.httpsProxy);
2065+
sdkConfigLog.setConnectTimeout(this.getConnectTimeout());
2066+
sdkConfigLog.setReadTimeout(this.getReadTimeout());
2067+
sdkConfigLog.setWriteTimeout(this.getWriteTimeout());
2068+
sdkConfigLog.setAutoRetry(this.autoRetry);
2069+
sdkConfigLog.setMinRetryDelayMs(this.getMinRetryDelayMs());
2070+
sdkConfigLog.setMaxRetryDelayMs(this.getMaxRetryDelayMs());
2071+
sdkConfigLog.setRetryCondition(this.getRetryCondition());
2072+
sdkConfigLog.setBackoffStrategy(this.getBackoffStrategy());
2073+
sdkConfigLog.setRetryErrorCode(this.getRetryErrorCodes());
2074+
sdkConfigLog.setRegion(this.region);
2075+
sdkConfigLog.setEndpoint(this.endpoint);
2076+
sdkConfigLog.setUseDualStack(this.useDualStack);
2077+
sdkConfigLog.setCustomBootstrapRegion(this.customBootstrapRegion);
2078+
sdkConfigLog.setEndpointResolver(this.endpointResolver);
2079+
sdkConfigLog.log();
2080+
this.sdkConfigLog = sdkConfigLog;
2081+
}
2082+
2083+
}
20112084
}

volcengine-java-sdk-core/src/main/java/com/volcengine/endpoint/DefaultEndpointProvider.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.HashSet;
77
import java.util.Map;
88
import java.util.Set;
9+
import static com.volcengine.observability.debugger.SdkDebugLog.SDK_CORE_LOGGER;
910

1011
public class DefaultEndpointProvider implements EndpointResolver {
1112

@@ -743,30 +744,37 @@ private static String getDefaultEndpointByServiceInfo(String service, String reg
743744
String resultEndpoint = ENDPOINT;
744745
ServiceEndpointInfo endpointInfo = DEFAULT_ENDPOINT_MAP.get(service);
745746
if (endpointInfo == null || !inBootstrapRegionList(regionCode, customBootstrapRegion)) {
747+
SDK_CORE_LOGGER.debugEndpoint("Service '{}' not found in default endpoint map, fallback to default: {}, Or Region '{}' not in bootstrap region list, fallback to default: {}", service, resultEndpoint, regionCode, resultEndpoint);
746748
return resultEndpoint;
747749
}
748750

751+
749752
String endpointSuffix = hasEnabledDualstack(useDualStack) ? DUALSTACK_ENDPOINT_SUFFIX : ENDPOINT_SUFFIX;
753+
SDK_CORE_LOGGER.debugEndpoint("Endpoint suffix is: " + endpointSuffix);
750754

751755
if (endpointInfo.isGlobal) {
752756
if (!endpointInfo.globalEndpoint.isEmpty()) {
757+
SDK_CORE_LOGGER.debugEndpoint("Service '{}' is global, using predefined global endpoint: {}", service, resultEndpoint);
753758
resultEndpoint = endpointInfo.globalEndpoint;
754759
return resultEndpoint;
755760
}
756761

757762
resultEndpoint = standardizeDomainServiceCode(service) + endpointSuffix;
763+
SDK_CORE_LOGGER.debugEndpoint("Service '{}' is global, constructing endpoint: {}", service, resultEndpoint);
758764
return resultEndpoint;
759765
}
760766

761767
if (endpointInfo.regionEndpointMap != null) {
762768
String regionEndpoint = endpointInfo.regionEndpointMap.get(regionCode);
763769
if (regionEndpoint != null) {
764770
resultEndpoint = regionEndpoint;
771+
SDK_CORE_LOGGER.debugEndpoint("Found predefined endpoint for service '{}' in region '{}': {}", service, regionCode, resultEndpoint);
765772
return resultEndpoint;
766773
}
767774
}
768775

769776
resultEndpoint = standardizeDomainServiceCode(service) + SEPARATOR + regionCode + endpointSuffix;
777+
SDK_CORE_LOGGER.debugEndpoint("Constructing endpoint for service '{}' in region '{}': {}", service, regionCode, resultEndpoint);
770778
return resultEndpoint;
771779
}
772780

@@ -775,6 +783,7 @@ private static boolean inBootstrapRegionList(String region, Set<String> customBo
775783
String bsRegionListPath = System.getenv("VOLC_BOOTSTRAP_REGION_LIST_CONF");
776784

777785
if (bsRegionListPath != null && !bsRegionListPath.isEmpty()) {
786+
SDK_CORE_LOGGER.debugEndpoint("Checking for region in file specified by VOLC_BOOTSTRAP_REGION_LIST_CONF: " + bsRegionListPath);
778787
try {
779788
BufferedReader reader = new BufferedReader(new FileReader(bsRegionListPath));
780789
String line;
@@ -785,23 +794,28 @@ private static boolean inBootstrapRegionList(String region, Set<String> customBo
785794
}
786795
if (line.equals(regionCode)) {
787796
reader.close();
797+
SDK_CORE_LOGGER.debugEndpoint("Region '{}' found in {}.", regionCode, bsRegionListPath);
788798
return true;
789799
}
790800
}
791801
reader.close();
792802
} catch (Exception e) {
793-
System.err.println("Error when reading " + bsRegionListPath + ": " + e.getMessage());
803+
SDK_CORE_LOGGER.error(()->"Error when reading " + bsRegionListPath + ": ", e);
794804
}
795805
}
796806

797807
if (BOOTSTRAP_REGION.contains(region)) {
808+
SDK_CORE_LOGGER.debugEndpoint("Region '{}' found in default bootstrap list.", region);
798809
return true;
799810
}
800811

801-
if (customBootstrapRegion != null) {
802-
return customBootstrapRegion.contains(region);
812+
if (customBootstrapRegion != null && customBootstrapRegion.contains(region)) {
813+
SDK_CORE_LOGGER.debugEndpoint("Region '{}' found in custom bootstrap list.", region);
814+
return true;
803815
}
804816

817+
SDK_CORE_LOGGER.debugEndpoint("Region '{}' not found in any bootstrap list.", region);
818+
805819
return false;
806820
}
807821

volcengine-java-sdk-core/src/main/java/com/volcengine/endpoint/EndpointResolver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
public interface EndpointResolver {
44

5-
public ResolvedEndpoint endpointFor(ResolveEndpointOption option);
5+
ResolvedEndpoint endpointFor(ResolveEndpointOption option);
6+
67
}

0 commit comments

Comments
 (0)