diff --git a/governance/src/main/java/org/apache/servicecomb/governance/GovernanceConfiguration.java b/governance/src/main/java/org/apache/servicecomb/governance/GovernanceConfiguration.java index a89ae12f702..a1ca1356072 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/GovernanceConfiguration.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/GovernanceConfiguration.java @@ -127,9 +127,8 @@ public LoadBalanceHandler loadBalanceHandler(LoadBalanceProperties loadBalancePr @Bean public CircuitBreakerHandler circuitBreakerHandler(CircuitBreakerProperties circuitBreakerProperties, - AbstractCircuitBreakerExtension circuitBreakerExtension, - ObjectProvider meterRegistry) { - return new CircuitBreakerHandler(circuitBreakerProperties, circuitBreakerExtension, meterRegistry); + AbstractCircuitBreakerExtension circuitBreakerExtension) { + return new CircuitBreakerHandler(circuitBreakerProperties, circuitBreakerExtension); } @Bean diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/AbstractGovernanceHandler.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/AbstractGovernanceHandler.java index f66c88c471c..631fc87fe1b 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/AbstractGovernanceHandler.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/handler/AbstractGovernanceHandler.java @@ -28,6 +28,8 @@ import com.google.common.eventbus.Subscribe; +import io.micrometer.core.instrument.MeterRegistry; + public abstract class AbstractGovernanceHandler { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractGovernanceHandler.class); @@ -37,6 +39,8 @@ public abstract class AbstractGovernanceHandler(this::onConfigurationChanged); @@ -47,6 +51,11 @@ public void setMatchersManager(MatchersManager matchersManager) { this.matchersManager = matchersManager; } + @Autowired(required = false) + public void setMeterRegistry(MeterRegistry meterRegistry) { + this.meterRegistry = meterRegistry; + } + public PROCESSOR getActuator(GovernanceRequest governanceRequest) { POLICY policy = matchPolicy(governanceRequest); if (policy == null) { diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/BulkheadHandler.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/BulkheadHandler.java index 2f5a1213018..4b09cce0088 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/BulkheadHandler.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/handler/BulkheadHandler.java @@ -28,6 +28,8 @@ import io.github.resilience4j.bulkhead.Bulkhead; import io.github.resilience4j.bulkhead.BulkheadConfig; import io.github.resilience4j.bulkhead.BulkheadRegistry; +import io.github.resilience4j.micrometer.tagged.BulkheadMetricNames; +import io.github.resilience4j.micrometer.tagged.TaggedBulkheadMetrics; public class BulkheadHandler extends AbstractGovernanceHandler { private static final Logger LOGGER = LoggerFactory.getLogger(BulkheadHandler.class); @@ -40,7 +42,7 @@ public BulkheadHandler(BulkheadProperties bulkheadProperties) { @Override protected String createKey(GovernanceRequest governanceRequest, BulkheadPolicy policy) { - return BulkheadProperties.MATCH_BULKHEAD__KEY + "." + policy.getName(); + return BulkheadProperties.MATCH_BULKHEAD_KEY + "." + policy.getName(); } @Override @@ -62,7 +64,14 @@ private Disposable getBulkhead(String key, BulkheadPolicy policy) { .build(); BulkheadRegistry registry = BulkheadRegistry.of(config); - + if (meterRegistry != null) { + TaggedBulkheadMetrics + .ofBulkheadRegistry(BulkheadMetricNames.custom() + .availableConcurrentCallsMetricName(BulkheadProperties.MATCH_BULKHEAD_KEY + ".available.concurrent.calls") + .maxAllowedConcurrentCallsMetricName( + BulkheadProperties.MATCH_BULKHEAD_KEY + ".max.allowed.concurrent.calls").build(), registry) + .bindTo(meterRegistry); + } return new DisposableBulkhead(key, registry, registry.bulkhead(key)); } } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/CircuitBreakerHandler.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/CircuitBreakerHandler.java index d51bb5f2d43..fccbbfd7c11 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/CircuitBreakerHandler.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/handler/CircuitBreakerHandler.java @@ -24,13 +24,12 @@ import org.apache.servicecomb.governance.properties.CircuitBreakerProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.ObjectProvider; import io.github.resilience4j.circuitbreaker.CircuitBreaker; import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.micrometer.tagged.CircuitBreakerMetricNames; import io.github.resilience4j.micrometer.tagged.TaggedCircuitBreakerMetrics; -import io.micrometer.core.instrument.MeterRegistry; public class CircuitBreakerHandler extends AbstractGovernanceHandler { private static final Logger LOGGER = LoggerFactory.getLogger(CircuitBreakerHandler.class); @@ -39,14 +38,10 @@ public class CircuitBreakerHandler extends AbstractGovernanceHandler meterRegistry) { + AbstractCircuitBreakerExtension circuitBreakerExtension) { this.circuitBreakerProperties = circuitBreakerProperties; this.circuitBreakerExtension = circuitBreakerExtension; - this.meterRegistry = meterRegistry.getIfAvailable(); } @Override @@ -83,7 +78,15 @@ private Disposable getCircuitBreaker(String key, CircuitBreakerP CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(circuitBreakerConfig); if (meterRegistry != null) { TaggedCircuitBreakerMetrics - .ofCircuitBreakerRegistry(circuitBreakerRegistry) + .ofCircuitBreakerRegistry(CircuitBreakerMetricNames.custom() + .callsMetricName(CircuitBreakerProperties.MATCH_CIRCUITBREAKER_KEY + ".calls") + .notPermittedCallsMetricName(CircuitBreakerProperties.MATCH_CIRCUITBREAKER_KEY + ".not.permitted.calls") + .stateMetricName(CircuitBreakerProperties.MATCH_CIRCUITBREAKER_KEY + ".state") + .bufferedCallsMetricName(CircuitBreakerProperties.MATCH_CIRCUITBREAKER_KEY + ".buffered.calls") + .slowCallsMetricName(CircuitBreakerProperties.MATCH_CIRCUITBREAKER_KEY + ".slow.calls") + .failureRateMetricName(CircuitBreakerProperties.MATCH_CIRCUITBREAKER_KEY + ".failure.rate") + .slowCallRateMetricName(CircuitBreakerProperties.MATCH_CIRCUITBREAKER_KEY + ".slow.call.rate") + .build(), circuitBreakerRegistry) .bindTo(meterRegistry); } return new DisposableCircuitBreaker(key, circuitBreakerRegistry, diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/HandlerType.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/HandlerType.java deleted file mode 100644 index 5ae9b9ddb87..00000000000 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/HandlerType.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.servicecomb.governance.handler; - -public enum HandlerType { - CLIENT, - SERVER, - BOTH -} diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/IdentifierRateLimitingHandler.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/IdentifierRateLimitingHandler.java index 4c40aff0fd6..8b704e4aa57 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/IdentifierRateLimitingHandler.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/handler/IdentifierRateLimitingHandler.java @@ -26,6 +26,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.github.resilience4j.micrometer.tagged.RateLimiterMetricNames; +import io.github.resilience4j.micrometer.tagged.TaggedRateLimiterMetrics; import io.github.resilience4j.ratelimiter.RateLimiter; import io.github.resilience4j.ratelimiter.RateLimiterConfig; import io.github.resilience4j.ratelimiter.RateLimiterRegistry; @@ -81,13 +83,22 @@ public Disposable createProcessor(String key, GovernanceRequest gov private Disposable getRateLimiter(String key, IdentifierRateLimitingPolicy policy) { LOGGER.info("applying new policy {} for {}", key, policy.toString()); - RateLimiterConfig config; - config = RateLimiterConfig.custom() + RateLimiterConfig config = RateLimiterConfig.custom() .limitForPeriod(policy.getRate()) .limitRefreshPeriod(Duration.parse(policy.getLimitRefreshPeriod())) .timeoutDuration(Duration.parse(policy.getTimeoutDuration())) .build(); RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); + if (meterRegistry != null) { + TaggedRateLimiterMetrics + .ofRateLimiterRegistry(RateLimiterMetricNames.custom() + .availablePermissionsMetricName( + IdentifierRateLimitProperties.MATCH_RATE_LIMIT_KEY + ".available.permissions") + .waitingThreadsMetricName(IdentifierRateLimitProperties.MATCH_RATE_LIMIT_KEY + ".waiting.threads") + .build(), + rateLimiterRegistry) + .bindTo(meterRegistry); + } return new DisposableRateLimiter(key, rateLimiterRegistry.rateLimiter(key), rateLimiterRegistry); } } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceBulkheadHandler.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceBulkheadHandler.java index 8b535b2f8a6..0f8e5d6b524 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceBulkheadHandler.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceBulkheadHandler.java @@ -29,6 +29,8 @@ import io.github.resilience4j.bulkhead.Bulkhead; import io.github.resilience4j.bulkhead.BulkheadConfig; import io.github.resilience4j.bulkhead.BulkheadRegistry; +import io.github.resilience4j.micrometer.tagged.BulkheadMetricNames; +import io.github.resilience4j.micrometer.tagged.TaggedBulkheadMetrics; public class InstanceBulkheadHandler extends AbstractGovernanceHandler { private static final Logger LOGGER = LoggerFactory.getLogger(InstanceBulkheadHandler.class); @@ -86,7 +88,16 @@ private Disposable getBulkhead(String key, BulkheadPolicy policy) { .build(); BulkheadRegistry registry = BulkheadRegistry.of(config); - + if (meterRegistry != null) { + TaggedBulkheadMetrics + .ofBulkheadRegistry(BulkheadMetricNames.custom() + .availableConcurrentCallsMetricName( + InstanceBulkheadProperties.MATCH_INSTANCE_BULKHEAD_KEY + ".available.concurrent.calls") + .maxAllowedConcurrentCallsMetricName( + InstanceBulkheadProperties.MATCH_INSTANCE_BULKHEAD_KEY + ".max.allowed.concurrent.calls").build(), + registry) + .bindTo(meterRegistry); + } return new DisposableBulkhead(key, registry, registry.bulkhead(key, config)); } } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceIsolationHandler.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceIsolationHandler.java index a91f2595e89..14ce4617786 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceIsolationHandler.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/handler/InstanceIsolationHandler.java @@ -31,6 +31,7 @@ import io.github.resilience4j.circuitbreaker.CircuitBreaker; import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.micrometer.tagged.CircuitBreakerMetricNames; import io.github.resilience4j.micrometer.tagged.TaggedCircuitBreakerMetrics; import io.micrometer.core.instrument.MeterRegistry; @@ -108,7 +109,16 @@ private Disposable getCircuitBreaker(String key, CircuitBreakerP CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.of(circuitBreakerConfig); if (meterRegistry != null) { TaggedCircuitBreakerMetrics - .ofCircuitBreakerRegistry(circuitBreakerRegistry) + .ofCircuitBreakerRegistry(CircuitBreakerMetricNames.custom() + .callsMetricName(InstanceIsolationProperties.MATCH_INSTANCE_ISOLATION_KEY + ".calls") + .notPermittedCallsMetricName( + InstanceIsolationProperties.MATCH_INSTANCE_ISOLATION_KEY + ".not.permitted.calls") + .stateMetricName(InstanceIsolationProperties.MATCH_INSTANCE_ISOLATION_KEY + ".state") + .bufferedCallsMetricName(InstanceIsolationProperties.MATCH_INSTANCE_ISOLATION_KEY + ".buffered.calls") + .slowCallsMetricName(InstanceIsolationProperties.MATCH_INSTANCE_ISOLATION_KEY + ".slow.calls") + .failureRateMetricName(InstanceIsolationProperties.MATCH_INSTANCE_ISOLATION_KEY + ".failure.rate") + .slowCallRateMetricName(InstanceIsolationProperties.MATCH_INSTANCE_ISOLATION_KEY + ".slow.call.rate") + .build(), circuitBreakerRegistry) .bindTo(meterRegistry); } return new DisposableCircuitBreaker(key, circuitBreakerRegistry, diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/RateLimitingHandler.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/RateLimitingHandler.java index 22a120925ce..b4653bf8c1e 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/RateLimitingHandler.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/handler/RateLimitingHandler.java @@ -24,6 +24,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import io.github.resilience4j.micrometer.tagged.RateLimiterMetricNames; +import io.github.resilience4j.micrometer.tagged.TaggedRateLimiterMetrics; import io.github.resilience4j.ratelimiter.RateLimiter; import io.github.resilience4j.ratelimiter.RateLimiterConfig; import io.github.resilience4j.ratelimiter.RateLimiterRegistry; @@ -62,6 +64,16 @@ private Disposable getRateLimiter(String key, RateLimitingPolicy po .timeoutDuration(Duration.parse(policy.getTimeoutDuration())) .build(); RateLimiterRegistry rateLimiterRegistry = RateLimiterRegistry.of(config); + if (meterRegistry != null) { + TaggedRateLimiterMetrics + .ofRateLimiterRegistry(RateLimiterMetricNames.custom() + .availablePermissionsMetricName( + RateLimitProperties.MATCH_RATE_LIMIT_KEY + ".available.permissions") + .waitingThreadsMetricName(RateLimitProperties.MATCH_RATE_LIMIT_KEY + ".waiting.threads") + .build(), + rateLimiterRegistry) + .bindTo(meterRegistry); + } return new DisposableRateLimiter(key, rateLimiterRegistry.rateLimiter(key), rateLimiterRegistry); } } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/handler/RetryHandler.java b/governance/src/main/java/org/apache/servicecomb/governance/handler/RetryHandler.java index 2fb571a45ce..b46f7d4066c 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/handler/RetryHandler.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/handler/RetryHandler.java @@ -27,6 +27,8 @@ import org.slf4j.LoggerFactory; import io.github.resilience4j.core.IntervalFunction; +import io.github.resilience4j.micrometer.tagged.RetryMetricNames; +import io.github.resilience4j.micrometer.tagged.TaggedRetryMetrics; import io.github.resilience4j.retry.Retry; import io.github.resilience4j.retry.RetryConfig; import io.github.resilience4j.retry.RetryRegistry; @@ -71,6 +73,14 @@ private Disposable getRetry(String key, RetryPolicy retryPolicy) { .build(); RetryRegistry registry = RetryRegistry.of(config); + if (meterRegistry != null) { + TaggedRetryMetrics + .ofRetryRegistry(RetryMetricNames.custom() + .callsMetricName(RetryProperties.MATCH_RETRY_KEY + ".calls") + .build(), + registry) + .bindTo(meterRegistry); + } return new DisposableRetry(key, registry, registry.retry(key)); } diff --git a/governance/src/main/java/org/apache/servicecomb/governance/properties/BulkheadProperties.java b/governance/src/main/java/org/apache/servicecomb/governance/properties/BulkheadProperties.java index 28daf001891..6bef14c746c 100644 --- a/governance/src/main/java/org/apache/servicecomb/governance/properties/BulkheadProperties.java +++ b/governance/src/main/java/org/apache/servicecomb/governance/properties/BulkheadProperties.java @@ -20,10 +20,10 @@ import org.apache.servicecomb.governance.policy.BulkheadPolicy; public class BulkheadProperties extends PolicyProperties { - public static final String MATCH_BULKHEAD__KEY = "servicecomb.bulkhead"; + public static final String MATCH_BULKHEAD_KEY = "servicecomb.bulkhead"; public BulkheadProperties() { - super(MATCH_BULKHEAD__KEY); + super(MATCH_BULKHEAD_KEY); } @Override diff --git a/governance/src/test/java/org/apache/servicecomb/governance/InstanceIsolationTest.java b/governance/src/test/java/org/apache/servicecomb/governance/InstanceIsolationTest.java index 6054477abdb..b781dc4c5cc 100644 --- a/governance/src/test/java/org/apache/servicecomb/governance/InstanceIsolationTest.java +++ b/governance/src/test/java/org/apache/servicecomb/governance/InstanceIsolationTest.java @@ -115,24 +115,24 @@ public void test_instance_isolation_work() throws Throwable { private void assertMetricsNotFinish() { String result = ((PrometheusMeterRegistry) meterRegistry).scrape(); Assertions.assertTrue(result.contains( - "resilience4j_circuitbreaker_state{name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\",state=\"open\",} 1.0")); + "servicecomb_instanceIsolation_state{name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\",state=\"open\",} 1.0")); Assertions.assertTrue(result.contains( - "resilience4j_circuitbreaker_state{name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\",state=\"closed\",} 1.0")); + "servicecomb_instanceIsolation_state{name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\",state=\"closed\",} 1.0")); Assertions.assertTrue(result.contains( - "resilience4j_circuitbreaker_calls_seconds_count{kind=\"successful\",name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\",} 1.0")); + "servicecomb_instanceIsolation_calls_seconds_count{kind=\"successful\",name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\",} 1.0")); Assertions.assertTrue(result.contains( - "resilience4j_circuitbreaker_calls_seconds_count{kind=\"successful\",name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\",} 4.0")); + "servicecomb_instanceIsolation_calls_seconds_count{kind=\"successful\",name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\",} 4.0")); } private void assertMetricsFinish() { String result = ((PrometheusMeterRegistry) meterRegistry).scrape(); Assertions.assertTrue(result.contains( - "resilience4j_circuitbreaker_state{name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\",state=\"closed\",} 1.0")); + "servicecomb_instanceIsolation_state{name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\",state=\"closed\",} 1.0")); Assertions.assertTrue(result.contains( - "resilience4j_circuitbreaker_state{name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\",state=\"closed\",} 1.0")); + "servicecomb_instanceIsolation_state{name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\",state=\"closed\",} 1.0")); Assertions.assertTrue(result.contains( - "resilience4j_circuitbreaker_calls_seconds_count{kind=\"successful\",name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\",} 3.0")); + "servicecomb_instanceIsolation_calls_seconds_count{kind=\"successful\",name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance01\",} 3.0")); Assertions.assertTrue(result.contains( - "resilience4j_circuitbreaker_calls_seconds_count{kind=\"successful\",name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\",} 6.0")); + "servicecomb_instanceIsolation_calls_seconds_count{kind=\"successful\",name=\"servicecomb.instanceIsolation.demo-allOperation.service01.instance02\",} 6.0")); } }