diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index b44059e7..8de18274 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -17,7 +17,7 @@ given the ability to merge pull requests.
## Code of Conduct
This project adheres to the Contributor Covenant [code of
-conduct](https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/src/main/asciidoc/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
+conduct](https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/modules/ROOT/partials/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
unacceptable behavior to spring-code-of-conduct@pivotal.io.
## Code Conventions and Housekeeping
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 7979a5c5..9d5357d8 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -31,7 +31,7 @@ jobs:
- name: Build with Maven
run: ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
- name: Publish Test Report
- uses: mikepenz/action-junit-report@v4
+ uses: mikepenz/action-junit-report@v5
if: always() # always run even if the previous step fails
with:
report_paths: '**/surefire-reports/TEST-*.xml'
diff --git a/README.adoc b/README.adoc
index 97139044..03410549 100644
--- a/README.adoc
+++ b/README.adoc
@@ -121,9 +121,9 @@ given the ability to merge pull requests.
[[code-of-conduct]]
== Code of Conduct
-This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/src/main/asciidoc/code-of-conduct.adoc[code of
+This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/modules/ROOT/partials/code-of-conduct.adoc[code of
conduct]. By participating, you are expected to uphold this code. Please report
-unacceptable behavior to spring-code-of-conduct@pivotal.io.
+unacceptable behavior to code-of-conduct@spring.io.
[[code-conventions-and-housekeeping]]
== Code Conventions and Housekeeping
diff --git a/docs/antora.yml b/docs/antora.yml
index ab1a8894..59ebef94 100644
--- a/docs/antora.yml
+++ b/docs/antora.yml
@@ -6,7 +6,7 @@ nav:
ext:
collector:
run:
- command: ./mvnw --no-transfer-progress -B process-resources -Pdocs -pl docs -Dantora-maven-plugin.phase=none -Dgenerate-docs.phase=none -Dgenerate-readme.phase=none -Dgenerate-cloud-resources.phase=none -Dmaven-dependency-plugin-for-docs.phase=none -Dmaven-dependency-plugin-for-docs-classes.phase=none -DskipTests
+ command: ./mvnw --no-transfer-progress -B process-resources -Pdocs -pl docs -Dantora-maven-plugin.phase=none -Dgenerate-docs.phase=none -Dgenerate-readme.phase=none -Dgenerate-cloud-resources.phase=none -Dmaven-dependency-plugin-for-docs.phase=none -Dmaven-dependency-plugin-for-docs-classes.phase=none -DskipTests -DdisableConfigurationProperties
local: true
scan:
dir: ./target/classes/antora-resources/
diff --git a/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc b/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc
index 2bac92d3..6468a80f 100644
--- a/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc
+++ b/docs/modules/ROOT/pages/spring-cloud-commons/loadbalancer.adoc
@@ -506,6 +506,12 @@ set the value of the `spring.cloud.loadbalancer.stats.micrometer.enabled` to `tr
Additional information regarding the service instances, request data, and response data is added to metrics via tags whenever available.
+NOTE: For `WebClient` and `RestClient`-backed load-balancing, we use `uriTemplate` for the `uri` tag whenever available.
+
+TIP: It is possible to disable adding `path` to `uri` tag by setting `spring.cloud.loadbalancer.stats.include-path` to `false`.
+
+WARNING: As with `RestTemplate`-backed load-balancing, we don't have access to `uriTemplate`, full path is always used in the `uri` tag. In order to avoid high cardinality issues, if path is a high cardinality value (for example, `/orders/\{id\}`, where `id` takes a big number of values), it is strongly recommended to disable adding path to `uri` tag by setting `spring.cloud.loadbalancer.stats.include-path` to `false`.
+
NOTE: For some implementations, such as `BlockingLoadBalancerClient`, request and response data might not be available, as we establish generic types from arguments and might not be able to determine the types and read the data.
NOTE: The meters are registered in the registry when at least one record is added for a given meter.
diff --git a/docs/modules/ROOT/partials/_configprops.adoc b/docs/modules/ROOT/partials/_configprops.adoc
index 0f7da897..7d261e79 100644
--- a/docs/modules/ROOT/partials/_configprops.adoc
+++ b/docs/modules/ROOT/partials/_configprops.adoc
@@ -66,6 +66,7 @@
|spring.cloud.loadbalancer.retry.retryable-exceptions | `+++{}+++` | A `Set` of `Throwable` classes that should trigger a retry.
|spring.cloud.loadbalancer.retry.retryable-status-codes | `+++{}+++` | A `Set` of status codes that should trigger a retry.
|spring.cloud.loadbalancer.service-discovery.timeout | | String representation of Duration of the timeout for calls to service discovery.
+|spring.cloud.loadbalancer.stats.include-path | `+++true+++` | Indicates whether the {@code path} should be added to {@code uri} tag in metrics. When {@link RestTemplate} is used to execute load-balanced requests with high cardinality paths, setting it to {@code false} is recommended.
|spring.cloud.loadbalancer.stats.micrometer.enabled | `+++false+++` | Enables Spring Cloud LoadBalancer Micrometer stats.
|spring.cloud.loadbalancer.sticky-session.add-service-instance-cookie | `+++false+++` | Indicates whether a cookie with the newly selected instance should be added by LoadBalancer.
|spring.cloud.loadbalancer.sticky-session.instance-id-cookie-name | `+++sc-lb-instance-id+++` | The name of the cookie holding the preferred instance id.
diff --git a/docs/package.json b/docs/package.json
index 1c8155de..567c1f3a 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -1,8 +1,8 @@
{
"dependencies": {
- "antora": "3.2.0-alpha.6",
+ "antora": "3.2.0-alpha.8",
"@antora/atlas-extension": "1.0.0-alpha.2",
- "@antora/collector-extension": "1.0.0-beta.3",
+ "@antora/collector-extension": "1.0.1",
"@asciidoctor/tabs": "1.0.0-beta.6",
"@springio/antora-extensions": "1.14.2",
"@springio/asciidoctor-extensions": "1.0.0-alpha.14"
diff --git a/docs/pom.xml b/docs/pom.xml
index 655955a7..e9f98a28 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -8,7 +8,7 @@
org.springframework.cloudspring-cloud-commons-parent
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOTjarSpring Cloud Commons Docs
@@ -26,20 +26,28 @@
.*${maven.multiModuleProjectDirectory}/docs/modules/ROOT/partials/
-
-
- ${project.groupId}
- spring-cloud-starter
-
-
- ${project.groupId}
- spring-cloud-starter-loadbalancer
-
- src/main/asciidoc
+
+ enable-configuration-properties
+
+
+ !disableConfigurationProperties
+
+
+
+
+ ${project.groupId}
+ spring-cloud-starter
+
+
+ ${project.groupId}
+ spring-cloud-starter-loadbalancer
+
+
+ docs
diff --git a/pom.xml b/pom.xml
index b8a53a12..8b6f2781 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0org.springframework.cloudspring-cloud-commons-parent
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOTpomSpring Cloud Commons ParentSpring Cloud Commons Parent
@@ -13,7 +13,7 @@
org.springframework.cloudspring-cloud-build
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOT
diff --git a/spring-cloud-commons-dependencies/pom.xml b/spring-cloud-commons-dependencies/pom.xml
index c6399daa..af72a3c7 100644
--- a/spring-cloud-commons-dependencies/pom.xml
+++ b/spring-cloud-commons-dependencies/pom.xml
@@ -6,11 +6,11 @@
spring-cloud-dependencies-parentorg.springframework.cloud
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOTspring-cloud-commons-dependencies
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOTpomspring-cloud-commons-dependenciesSpring Cloud Commons Dependencies
diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml
index 64d61129..a0c55a7c 100644
--- a/spring-cloud-commons/pom.xml
+++ b/spring-cloud-commons/pom.xml
@@ -7,7 +7,7 @@
org.springframework.cloudspring-cloud-commons-parent
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOT..spring-cloud-commons
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java
index 39a0b1f9..49a0d80a 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,6 +33,7 @@ import org.springframework.cloud.commons.util.IdUtils;
import org.springframework.core.env.PropertyResolver;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedCaseInsensitiveMap;
+import org.springframework.web.client.RestTemplate;
/**
* The base configuration bean for Spring Cloud LoadBalancer.
@@ -90,10 +91,20 @@ public class LoadBalancerProperties {
/**
* Properties for
- * {@link org.springframework.cloud.loadbalancer.core.SubsetServiceInstanceListSupplier}.
+ * {@code org.springframework.cloud.loadbalancer.core.SubsetServiceInstanceListSupplier}.
*/
private Subset subset = new Subset();
+ /**
+ * Enabling X-Forwarded Host and Proto Headers.
+ */
+ private XForwarded xForwarded = new XForwarded();
+
+ /**
+ * Properties for LoadBalancer metrics.
+ */
+ private Stats stats = new Stats();
+
public HealthCheck getHealthCheck() {
return healthCheck;
}
@@ -134,11 +145,6 @@ public class LoadBalancerProperties {
this.hintHeaderName = hintHeaderName;
}
- /**
- * Enabling X-Forwarded Host and Proto Headers.
- */
- private XForwarded xForwarded = new XForwarded();
-
// TODO: fix spelling in a major release
public void setxForwarded(XForwarded xForwarded) {
this.xForwarded = xForwarded;
@@ -164,6 +170,14 @@ public class LoadBalancerProperties {
this.callGetWithRequestOnDelegates = callGetWithRequestOnDelegates;
}
+ public Stats getStats() {
+ return stats;
+ }
+
+ public void setStats(Stats stats) {
+ this.stats = stats;
+ }
+
public static class StickySession {
/**
@@ -539,4 +553,23 @@ public class LoadBalancerProperties {
}
+ public static class Stats {
+
+ /**
+ * Indicates whether the {@code path} should be added to {@code uri} tag in
+ * metrics. When {@link RestTemplate} is used to execute load-balanced requests
+ * with high cardinality paths, setting it to {@code false} is recommended.
+ */
+ private boolean includePath = true;
+
+ public boolean isIncludePath() {
+ return includePath;
+ }
+
+ public void setIncludePath(boolean includePath) {
+ this.includePath = includePath;
+ }
+
+ }
+
}
diff --git a/spring-cloud-context-integration-tests/pom.xml b/spring-cloud-context-integration-tests/pom.xml
index 00477adf..4d29611b 100644
--- a/spring-cloud-context-integration-tests/pom.xml
+++ b/spring-cloud-context-integration-tests/pom.xml
@@ -7,7 +7,7 @@
org.springframework.cloudspring-cloud-commons-parent
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOT..spring-cloud-context-integration-tests
diff --git a/spring-cloud-context-webflux-integration-tests/pom.xml b/spring-cloud-context-webflux-integration-tests/pom.xml
index 68986af6..84e83679 100644
--- a/spring-cloud-context-webflux-integration-tests/pom.xml
+++ b/spring-cloud-context-webflux-integration-tests/pom.xml
@@ -7,7 +7,7 @@
org.springframework.cloudspring-cloud-commons-parent
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOT..spring-cloud-context-webflux-integration-tests
diff --git a/spring-cloud-context/pom.xml b/spring-cloud-context/pom.xml
index 06db6b04..8eeb6c06 100644
--- a/spring-cloud-context/pom.xml
+++ b/spring-cloud-context/pom.xml
@@ -7,7 +7,7 @@
org.springframework.cloudspring-cloud-commons-parent
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOT..spring-cloud-context
diff --git a/spring-cloud-loadbalancer/pom.xml b/spring-cloud-loadbalancer/pom.xml
index 17051040..f8a0d717 100644
--- a/spring-cloud-loadbalancer/pom.xml
+++ b/spring-cloud-loadbalancer/pom.xml
@@ -6,7 +6,7 @@
org.springframework.cloudspring-cloud-commons-parent
- 4.2.0-SNAPSHOT
+ 4.2.1-SNAPSHOT..spring-cloud-loadbalancer
diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerStatsAutoConfiguration.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerStatsAutoConfiguration.java
index 1e609284..8e7de30d 100644
--- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerStatsAutoConfiguration.java
+++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/config/LoadBalancerStatsAutoConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,8 @@ import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancer;
import org.springframework.cloud.loadbalancer.stats.MicrometerStatsLoadBalancerLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -38,8 +40,9 @@ public class LoadBalancerStatsAutoConfiguration {
@Bean
@ConditionalOnBean(MeterRegistry.class)
- public MicrometerStatsLoadBalancerLifecycle micrometerStatsLifecycle(MeterRegistry meterRegistry) {
- return new MicrometerStatsLoadBalancerLifecycle(meterRegistry);
+ public MicrometerStatsLoadBalancerLifecycle micrometerStatsLifecycle(MeterRegistry meterRegistry,
+ ReactiveLoadBalancer.Factory loadBalancerFactory) {
+ return new MicrometerStatsLoadBalancerLifecycle(meterRegistry, loadBalancerFactory);
}
}
diff --git a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java
index 81c6d769..42afc64f 100644
--- a/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java
+++ b/spring-cloud-loadbalancer/src/main/java/org/springframework/cloud/loadbalancer/stats/LoadBalancerTags.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2020 the original author or authors.
+ * Copyright 2012-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,17 @@
package org.springframework.cloud.loadbalancer.stats;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.CompletionContext;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerProperties;
import org.springframework.cloud.client.loadbalancer.RequestData;
import org.springframework.cloud.client.loadbalancer.RequestDataContext;
import org.springframework.cloud.client.loadbalancer.ResponseData;
@@ -30,17 +36,25 @@ import org.springframework.util.StringUtils;
* Utility class for building metrics tags for load-balanced calls.
*
* @author Olga Maciaszek-Sharma
+ * @author Jaroslaw Dembek
* @since 3.0.0
*/
-final class LoadBalancerTags {
+class LoadBalancerTags {
static final String UNKNOWN = "UNKNOWN";
- private LoadBalancerTags() {
- throw new UnsupportedOperationException("Cannot instantiate utility class");
+ private final LoadBalancerProperties properties;
+
+ // Not using class references in case not in classpath
+ private static final Set URI_TEMPLATE_ATTRIBUTES = Set.of(
+ "org.springframework.web.reactive.function.client.WebClient.uriTemplate",
+ "org.springframework.web.client.RestClient.uriTemplate");
+
+ LoadBalancerTags(LoadBalancerProperties properties) {
+ this.properties = properties;
}
- static Iterable buildSuccessRequestTags(CompletionContext