|
56 | 56 | import com.couchbase.client.core.cnc.events.core.WatchdogRunFailedEvent; |
57 | 57 | import com.couchbase.client.core.cnc.events.transaction.TransactionsStartedEvent; |
58 | 58 | import com.couchbase.client.core.cnc.metrics.LoggingMeter; |
| 59 | +import com.couchbase.client.core.cnc.metrics.ResponseMetricIdentifier; |
59 | 60 | import com.couchbase.client.core.config.ClusterConfig; |
60 | 61 | import com.couchbase.client.core.config.ConfigurationProvider; |
61 | 62 | import com.couchbase.client.core.config.DefaultConfigurationProvider; |
|
75 | 76 | import com.couchbase.client.core.error.RequestCanceledException; |
76 | 77 | import com.couchbase.client.core.error.UnambiguousTimeoutException; |
77 | 78 | import com.couchbase.client.core.error.UnsupportedConfigMechanismException; |
78 | | -import com.couchbase.client.core.io.CollectionIdentifier; |
79 | 79 | import com.couchbase.client.core.manager.CoreBucketManagerOps; |
80 | 80 | import com.couchbase.client.core.manager.CoreCollectionManager; |
81 | 81 | import com.couchbase.client.core.msg.CancellationReason; |
82 | 82 | import com.couchbase.client.core.msg.Request; |
83 | 83 | import com.couchbase.client.core.msg.RequestContext; |
84 | 84 | import com.couchbase.client.core.msg.RequestTarget; |
85 | 85 | import com.couchbase.client.core.msg.Response; |
86 | | -import com.couchbase.client.core.msg.kv.KeyValueRequest; |
87 | | -import com.couchbase.client.core.msg.query.QueryRequest; |
88 | | -import com.couchbase.client.core.msg.search.ServerSearchRequest; |
89 | 86 | import com.couchbase.client.core.node.AnalyticsLocator; |
90 | 87 | import com.couchbase.client.core.node.KeyValueLocator; |
91 | 88 | import com.couchbase.client.core.node.Locator; |
|
118 | 115 | import java.time.Duration; |
119 | 116 | import java.util.ArrayList; |
120 | 117 | import java.util.Collection; |
121 | | -import java.util.HashMap; |
122 | 118 | import java.util.List; |
123 | 119 | import java.util.Map; |
124 | 120 | import java.util.NoSuchElementException; |
125 | | -import java.util.Objects; |
126 | 121 | import java.util.Optional; |
127 | 122 | import java.util.Set; |
128 | 123 | import java.util.concurrent.CompletableFuture; |
@@ -642,42 +637,10 @@ public ValueRecorder responseMetric(final Request<?> request, @Nullable Throwabl |
642 | 637 | exceptionSimpleName = err.getClass().getSimpleName().replace("Exception", ""); |
643 | 638 | } |
644 | 639 | } |
645 | | - final String finalExceptionSimpleName = exceptionSimpleName; |
646 | 640 | final ClusterIdentifier clusterIdent = ClusterIdentifierUtil.fromConfig(currentConfig); |
647 | 641 |
|
648 | | - return responseMetrics.computeIfAbsent(new ResponseMetricIdentifier(request, exceptionSimpleName, clusterIdent), key -> { |
649 | | - Map<String, String> tags = new HashMap<>(9); |
650 | | - tags.put(TracingIdentifiers.ATTR_SERVICE, key.serviceTracingId); |
651 | | - tags.put(TracingIdentifiers.ATTR_OPERATION, key.requestName); |
652 | | - |
653 | | - // The LoggingMeter only uses the service and operation labels, so optimise this hot-path by skipping |
654 | | - // assigning other labels. |
655 | | - if (!isDefaultLoggingMeter) { |
656 | | - // Crucial note for Micrometer: |
657 | | - // If we are ever going to output an attribute from a given JVM run then we must always |
658 | | - // output that attribute in this run. Specifying null as an attribute value allows the OTel backend to strip it, and |
659 | | - // the Micrometer backend to provide a default value. |
660 | | - // See (internal to Couchbase) discussion here for full details: |
661 | | - // https://issues.couchbase.com/browse/CBSE-17070?focusedId=779820&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-779820 |
662 | | - // If this rule is not followed, then Micrometer will silently discard some metrics. Micrometer requires that |
663 | | - // every value output under a given metric has the same set of attributes. |
664 | | - |
665 | | - tags.put(TracingIdentifiers.ATTR_NAME, key.bucketName); |
666 | | - tags.put(TracingIdentifiers.ATTR_SCOPE, key.scopeName); |
667 | | - tags.put(TracingIdentifiers.ATTR_COLLECTION, key.collectionName); |
668 | | - |
669 | | - tags.put(TracingIdentifiers.ATTR_CLUSTER_UUID, key.clusterUuid); |
670 | | - tags.put(TracingIdentifiers.ATTR_CLUSTER_NAME, key.clusterName); |
671 | | - |
672 | | - if (finalExceptionSimpleName != null) { |
673 | | - tags.put(TracingIdentifiers.ATTR_OUTCOME, finalExceptionSimpleName); |
674 | | - } else { |
675 | | - tags.put(TracingIdentifiers.ATTR_OUTCOME, "Success"); |
676 | | - } |
677 | | - } |
678 | | - |
679 | | - return coreContext.environment().meter().valueRecorder(TracingIdentifiers.METER_OPERATIONS, tags); |
680 | | - }); |
| 642 | + return responseMetrics.computeIfAbsent(ResponseMetricIdentifier.fromRequest(request, exceptionSimpleName, clusterIdent, isDefaultLoggingMeter),key -> |
| 643 | + coreContext.environment().meter().valueRecorder(TracingIdentifiers.METER_OPERATIONS, key.tags())); |
681 | 644 | } |
682 | 645 |
|
683 | 646 | /** |
@@ -1033,91 +996,6 @@ public CompletableFuture<Void> waitUntilReady( |
1033 | 996 | return WaitUntilReadyHelper.waitUntilReady(this, serviceTypes, timeout, desiredState, Optional.ofNullable(bucketName)); |
1034 | 997 | } |
1035 | 998 |
|
1036 | | - @Stability.Internal |
1037 | | - public static class ResponseMetricIdentifier { |
1038 | | - |
1039 | | - private final String serviceTracingId; |
1040 | | - private final String requestName; |
1041 | | - private final @Nullable String bucketName; |
1042 | | - private final @Nullable String scopeName; |
1043 | | - private final @Nullable String collectionName; |
1044 | | - private final @Nullable String exceptionSimpleName; |
1045 | | - private final @Nullable String clusterName; |
1046 | | - private final @Nullable String clusterUuid; |
1047 | | - |
1048 | | - ResponseMetricIdentifier(final Request<?> request, @Nullable String exceptionSimpleName, @Nullable ClusterIdentifier clusterIdent) { |
1049 | | - this.exceptionSimpleName = exceptionSimpleName; |
1050 | | - this.serviceTracingId = request.serviceTracingId(); |
1051 | | - this.requestName = request.name(); |
1052 | | - this.clusterName = clusterIdent == null ? null : clusterIdent.clusterName(); |
1053 | | - this.clusterUuid = clusterIdent == null ? null : clusterIdent.clusterUuid(); |
1054 | | - if (request instanceof KeyValueRequest) { |
1055 | | - KeyValueRequest<?> kv = (KeyValueRequest<?>) request; |
1056 | | - bucketName = request.bucket(); |
1057 | | - scopeName = kv.collectionIdentifier().scope().orElse(CollectionIdentifier.DEFAULT_SCOPE); |
1058 | | - collectionName = kv.collectionIdentifier().collection().orElse(CollectionIdentifier.DEFAULT_SCOPE); |
1059 | | - } else if (request instanceof QueryRequest) { |
1060 | | - QueryRequest query = (QueryRequest) request; |
1061 | | - bucketName = request.bucket(); |
1062 | | - scopeName = query.scope(); |
1063 | | - collectionName = null; |
1064 | | - } else if (request instanceof ServerSearchRequest) { |
1065 | | - ServerSearchRequest search = (ServerSearchRequest) request; |
1066 | | - if (search.scope() != null) { |
1067 | | - bucketName = search.scope().bucketName(); |
1068 | | - scopeName = search.scope().scopeName(); |
1069 | | - } else { |
1070 | | - bucketName = null; |
1071 | | - scopeName = null; |
1072 | | - } |
1073 | | - collectionName = null; |
1074 | | - } else { |
1075 | | - bucketName = null; |
1076 | | - scopeName = null; |
1077 | | - collectionName = null; |
1078 | | - } |
1079 | | - } |
1080 | | - |
1081 | | - public ResponseMetricIdentifier(final String serviceTracingId, final String requestName) { |
1082 | | - this.serviceTracingId = serviceTracingId; |
1083 | | - this.requestName = requestName; |
1084 | | - this.bucketName = null; |
1085 | | - this.scopeName = null; |
1086 | | - this.collectionName = null; |
1087 | | - this.exceptionSimpleName = null; |
1088 | | - this.clusterName = null; |
1089 | | - this.clusterUuid = null; |
1090 | | - } |
1091 | | - |
1092 | | - public String serviceTracingId() { |
1093 | | - return serviceTracingId; |
1094 | | - } |
1095 | | - |
1096 | | - public String requestName() { |
1097 | | - return requestName; |
1098 | | - } |
1099 | | - |
1100 | | - @Override |
1101 | | - public boolean equals(Object o) { |
1102 | | - if (this == o) return true; |
1103 | | - if (o == null || getClass() != o.getClass()) return false; |
1104 | | - ResponseMetricIdentifier that = (ResponseMetricIdentifier) o; |
1105 | | - return serviceTracingId.equals(that.serviceTracingId) |
1106 | | - && Objects.equals(requestName, that.requestName) |
1107 | | - && Objects.equals(bucketName, that.bucketName) |
1108 | | - && Objects.equals(scopeName, that.scopeName) |
1109 | | - && Objects.equals(collectionName, that.collectionName) |
1110 | | - && Objects.equals(exceptionSimpleName, that.exceptionSimpleName) |
1111 | | - && Objects.equals(clusterName, that.clusterName) |
1112 | | - && Objects.equals(clusterUuid, that.clusterUuid); |
1113 | | - } |
1114 | | - |
1115 | | - @Override |
1116 | | - public int hashCode() { |
1117 | | - return Objects.hash(serviceTracingId, requestName, bucketName, scopeName, collectionName, exceptionSimpleName, clusterName, clusterUuid); |
1118 | | - } |
1119 | | - } |
1120 | | - |
1121 | 999 | /** |
1122 | 1000 | * Watchdog responsible for checking for potentially invalid states and initiating corrective action. |
1123 | 1001 | * <p> |
|
0 commit comments