| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 3b83448 commit 11a362b
14 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -28,9 +28,6 @@ | |||
| 28 | 28 | import com.google.cloud.opentelemetry.detection.AttributeKeys; | |
| 29 | 29 | import com.google.cloud.opentelemetry.detection.DetectedPlatform; | |
| 30 | 30 | import com.google.cloud.opentelemetry.detection.GCPPlatformDetector; | |
| 31 | - import com.google.common.annotations.VisibleForTesting; | ||
| 32 | - import com.google.common.cache.Cache; | ||
| 33 | - import com.google.common.cache.CacheBuilder; | ||
| 34 | 31 | import com.google.common.hash.HashFunction; | |
| 35 | 32 | import com.google.common.hash.Hashing; | |
| 36 | 33 | import io.opentelemetry.api.OpenTelemetry; | |
@@ -49,81 +46,41 @@ | |||
| 49 | 46 | import java.util.logging.Logger; | |
| 50 | 47 | import javax.annotation.Nullable; | |
| 51 | 48 | ||
| 52 | - final class BuiltInOpenTelemetryMetricsProvider { | ||
| 49 | + final class BuiltInMetricsProvider { | ||
| 53 | 50 | ||
| 54 | - public static BuiltInOpenTelemetryMetricsProvider INSTANCE = | ||
| 55 | - new BuiltInOpenTelemetryMetricsProvider(); | ||
| 51 | + static BuiltInMetricsProvider INSTANCE = new BuiltInMetricsProvider(); | ||
| 56 | 52 | ||
| 57 | - private static final Logger logger = | ||
| 58 | - Logger.getLogger(BuiltInOpenTelemetryMetricsProvider.class.getName()); | ||
| 59 | - | ||
| 60 | - private final Cache<String, Map<String, String>> clientAttributesCache = | ||
| 61 | - CacheBuilder.newBuilder().maximumSize(1000).build(); | ||
| 53 | + private static final Logger logger = Logger.getLogger(BuiltInMetricsProvider.class.getName()); | ||
| 62 | 54 | ||
| 63 | 55 | private static String taskId; | |
| 64 | 56 | ||
| 65 | 57 | private OpenTelemetry openTelemetry; | |
| 66 | 58 | ||
| 67 | - private Map<String, String> clientAttributes; | ||
| 68 | - | ||
| 69 | - private boolean isInitialized; | ||
| 70 | - | ||
| 71 | - private BuiltInOpenTelemetryMetricsRecorder builtInOpenTelemetryMetricsRecorder; | ||
| 72 | - | ||
| 73 | - private BuiltInOpenTelemetryMetricsProvider() {}; | ||
| 74 | - | ||
| 75 | - void initialize( | ||
| 76 | - String projectId, | ||
| 77 | - String client_name, | ||
| 78 | - @Nullable Credentials credentials, | ||
| 79 | - @Nullable String monitoringHost) { | ||
| 59 | + private BuiltInMetricsProvider() {} | ||
| 80 | 60 | ||
| 61 | + OpenTelemetry getOrCreateOpenTelemetry( | ||
| 62 | + String projectId, @Nullable Credentials credentials, @Nullable String monitoringHost) { | ||
| 81 | 63 | try { | |
| 82 | - if (!isInitialized) { | ||
| 83 | - this.openTelemetry = createOpenTelemetry(projectId, credentials, monitoringHost); | ||
| 84 | - this.clientAttributes = createClientAttributes(projectId, client_name); | ||
| 85 | - this.builtInOpenTelemetryMetricsRecorder = | ||
| 86 | - new BuiltInOpenTelemetryMetricsRecorder(openTelemetry, clientAttributes); | ||
| 87 | - isInitialized = true; | ||
| 64 | + if (this.openTelemetry == null) { | ||
| 65 | + SdkMeterProviderBuilder sdkMeterProviderBuilder = SdkMeterProvider.builder(); | ||
| 66 | + BuiltInMetricsView.registerBuiltinMetrics( | ||
| 67 | + SpannerCloudMonitoringExporter.create(projectId, credentials, monitoringHost), | ||
| 68 | + sdkMeterProviderBuilder); | ||
| 69 | + SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); | ||
| 70 | + this.openTelemetry = OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); | ||
| 71 | + Runtime.getRuntime().addShutdownHook(new Thread(sdkMeterProvider::close)); | ||
| 88 | 72 | } | |
| 89 | - } catch (Exception ex) { | ||
| 73 | + return this.openTelemetry; | ||
| 74 | + } catch (IOException ex) { | ||
| 90 | 75 | logger.log( | |
| 91 | 76 | Level.WARNING, | |
| 92 | - "Unable to initialize OpenTelemetry object or attributes for client side metrics, will skip exporting client side metrics", | ||
| 77 | + "Unable to get OpenTelemetry object for client side metrics, will skip exporting client side metrics", | ||
| 93 | 78 | ex); | |
| 79 | + return null; | ||
| 94 | 80 | } | |
| 95 | 81 | } | |
| 96 | 82 | ||
| 97 | - @VisibleForTesting | ||
| 98 | - void initialize( | ||
| 99 | - OpenTelemetry openTelemetry, | ||
| 100 | - String projectId, | ||
| 101 | - String client_name, | ||
| 102 | - @Nullable Credentials credentials, | ||
| 103 | - @Nullable String monitoringHost) { | ||
| 104 | - initialize(projectId, client_name, credentials, monitoringHost); | ||
| 105 | - this.builtInOpenTelemetryMetricsRecorder = | ||
| 106 | - new BuiltInOpenTelemetryMetricsRecorder(openTelemetry, clientAttributes); | ||
| 107 | - } | ||
| 108 | - | ||
| 109 | - OpenTelemetry getOpenTelemetry() { | ||
| 110 | - return this.openTelemetry; | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | - Map<String, String> getClientAttributes() { | ||
| 114 | - return this.clientAttributes; | ||
| 115 | - } | ||
| 116 | - | ||
| 117 | - BuiltInOpenTelemetryMetricsRecorder getBuiltInOpenTelemetryMetricsRecorder() { | ||
| 118 | - return this.builtInOpenTelemetryMetricsRecorder; | ||
| 119 | - } | ||
| 120 | - | ||
| 121 | - @VisibleForTesting | ||
| 122 | - void reset() { | ||
| 123 | - isInitialized = false; | ||
| 124 | - } | ||
| 125 | - | ||
| 126 | - private Map<String, String> createClientAttributes(String projectId, String client_name) { | ||
| 83 | + Map<String, String> createClientAttributes(String projectId, String client_name) { | ||
| 127 | 84 | Map<String, String> clientAttributes = new HashMap<>(); | |
| 128 | 85 | clientAttributes.put(LOCATION_ID_KEY.getKey(), detectClientLocation()); | |
| 129 | 86 | clientAttributes.put(PROJECT_ID_KEY.getKey(), projectId); | |
@@ -135,20 +92,6 @@ private Map<String, String> createClientAttributes(String projectId, String clie | |||
| 135 | 92 | return clientAttributes; | |
| 136 | 93 | } | |
| 137 | 94 | ||
| 138 | - private OpenTelemetry createOpenTelemetry( | ||
| 139 | - String projectId, @Nullable Credentials credentials, @Nullable String monitoringHost) | ||
| 140 | - throws IOException { | ||
| 141 | - OpenTelemetry openTelemetry; | ||
| 142 | - SdkMeterProviderBuilder sdkMeterProviderBuilder = SdkMeterProvider.builder(); | ||
| 143 | - BuiltInOpenTelemetryMetricsView.registerBuiltinMetrics( | ||
| 144 | - SpannerCloudMonitoringExporter.create(projectId, credentials, monitoringHost), | ||
| 145 | - sdkMeterProviderBuilder); | ||
| 146 | - SdkMeterProvider sdkMeterProvider = sdkMeterProviderBuilder.build(); | ||
| 147 | - openTelemetry = OpenTelemetrySdk.builder().setMeterProvider(sdkMeterProvider).build(); | ||
| 148 | - Runtime.getRuntime().addShutdownHook(new Thread(sdkMeterProvider::close)); | ||
| 149 | - return openTelemetry; | ||
| 150 | - } | ||
| 151 | - | ||
| 152 | 95 | /** | |
| 153 | 96 | * Generates a 6-digit zero-padded all lower case hexadecimal representation of hash of the | |
| 154 | 97 | * accounting group. The hash utilizes the 10 most significant bits of the value returned by | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -17,21 +17,21 @@ | |||
| 17 | 17 | package com.google.cloud.spanner; | |
| 18 | 18 | ||
| 19 | 19 | import com.google.api.gax.core.GaxProperties; | |
| 20 | + import com.google.api.gax.tracing.OpenTelemetryMetricsRecorder; | ||
| 20 | 21 | import com.google.common.annotations.VisibleForTesting; | |
| 21 | 22 | import com.google.common.base.Preconditions; | |
| 22 | 23 | import io.opentelemetry.api.OpenTelemetry; | |
| 23 | 24 | import io.opentelemetry.api.common.Attributes; | |
| 24 | 25 | import io.opentelemetry.api.common.AttributesBuilder; | |
| 25 | 26 | import io.opentelemetry.api.metrics.DoubleHistogram; | |
| 26 | 27 | import io.opentelemetry.api.metrics.Meter; | |
| 27 | - import java.util.HashMap; | ||
| 28 | 28 | import java.util.Map; | |
| 29 | 29 | ||
| 30 | 30 | /** OpenTelemetry implementation of recording built in metrics. */ | |
| 31 | - public class BuiltInOpenTelemetryMetricsRecorder { | ||
| 31 | + public class BuiltInMetricsRecorder extends OpenTelemetryMetricsRecorder { | ||
| 32 | 32 | ||
| 33 | 33 | private final DoubleHistogram gfeLatencyRecorder; | |
| 34 | - private final Map<String, String> attributes = new HashMap<>(); | ||
| 34 | + // private final Map<String, String> attributes = new HashMap<>(); | ||
| 35 | 35 | ||
| 36 | 36 | /** | |
| 37 | 37 | * Creates the following instruments for the following metrics: | |
@@ -42,27 +42,20 @@ public class BuiltInOpenTelemetryMetricsRecorder { | |||
| 42 | 42 | * | |
| 43 | 43 | * @param openTelemetry OpenTelemetry instance | |
| 44 | 44 | */ | |
| 45 | - public BuiltInOpenTelemetryMetricsRecorder( | ||
| 46 | - OpenTelemetry openTelemetry, Map<String, String> clientAttributes) { | ||
| 47 | - if (openTelemetry == null || clientAttributes == null) { | ||
| 48 | - gfeLatencyRecorder = null; | ||
| 49 | - return; | ||
| 50 | - } | ||
| 51 | - | ||
| 45 | + public BuiltInMetricsRecorder(OpenTelemetry openTelemetry, String serviceName) { | ||
| 46 | + super(openTelemetry, serviceName); | ||
| 52 | 47 | Meter meter = | |
| 53 | 48 | openTelemetry | |
| 54 | 49 | .meterBuilder(BuiltInMetricsConstant.SPANNER_METER_NAME) | |
| 55 | 50 | .setInstrumentationVersion(GaxProperties.getLibraryVersion(getClass())) | |
| 56 | 51 | .build(); | |
| 57 | 52 | this.gfeLatencyRecorder = | |
| 58 | 53 | meter | |
| 59 | - .histogramBuilder( | ||
| 60 | - BuiltInMetricsConstant.METER_NAME + '/' + BuiltInMetricsConstant.GFE_LATENCIES_NAME) | ||
| 54 | + .histogramBuilder(serviceName + '/' + BuiltInMetricsConstant.GFE_LATENCIES_NAME) | ||
| 61 | 55 | .setDescription( | |
| 62 | 56 | "Latency between Google's network receiving an RPC and reading back the first byte of the response") | |
| 63 | 57 | .setUnit("ms") | |
| 64 | 58 | .build(); | |
| 65 | - this.attributes.putAll(clientAttributes); | ||
| 66 | 59 | } | |
| 67 | 60 | ||
| 68 | 61 | /** | |
@@ -73,10 +66,7 @@ public BuiltInOpenTelemetryMetricsRecorder( | |||
| 73 | 66 | * @param attributes Map of the attributes to store | |
| 74 | 67 | */ | |
| 75 | 68 | public void recordGFELatency(double gfeLatency, Map<String, String> attributes) { | |
| 76 | - if (gfeLatencyRecorder != null) { | ||
| 77 | - this.attributes.putAll(attributes); | ||
| 78 | - gfeLatencyRecorder.record(gfeLatency, toOtelAttributes(this.attributes)); | ||
| 79 | - } | ||
| 69 | + gfeLatencyRecorder.record(gfeLatency, toOtelAttributes(attributes)); | ||
| 80 | 70 | } | |
| 81 | 71 | ||
| 82 | 72 | @VisibleForTesting | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,53 @@ | |||
| 1 | + /* | ||
| 2 | + * Copyright 2024 Google LLC | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | + package com.google.cloud.spanner; | ||
| 18 | + | ||
| 19 | + import com.google.api.gax.tracing.MethodName; | ||
| 20 | + import com.google.api.gax.tracing.MetricsTracer; | ||
| 21 | + import java.util.HashMap; | ||
| 22 | + import java.util.Map; | ||
| 23 | + | ||
| 24 | + public class BuiltInMetricsTracer extends MetricsTracer { | ||
| 25 | + | ||
| 26 | + private final BuiltInMetricsRecorder builtInOpenTelemetryMetricsRecorder; | ||
| 27 | + // These are RPC specific attributes and pertain to a specific API Trace | ||
| 28 | + private final Map<String, String> attributes = new HashMap<>(); | ||
| 29 | + | ||
| 30 | + public BuiltInMetricsTracer( | ||
| 31 | + MethodName methodName, BuiltInMetricsRecorder builtInOpenTelemetryMetricsRecorder) { | ||
| 32 | + super(methodName, builtInOpenTelemetryMetricsRecorder); | ||
| 33 | + this.builtInOpenTelemetryMetricsRecorder = builtInOpenTelemetryMetricsRecorder; | ||
| 34 | + this.attributes.put(METHOD_ATTRIBUTE, methodName.toString()); | ||
| 35 | + this.attributes.put(LANGUAGE_ATTRIBUTE, DEFAULT_LANGUAGE); | ||
| 36 | + } | ||
| 37 | + | ||
| 38 | + public void recordGFELatency(double gfeLatency) { | ||
| 39 | + this.builtInOpenTelemetryMetricsRecorder.recordGFELatency(gfeLatency, this.attributes); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + @Override | ||
| 43 | + public void addAttributes(Map<String, String> attributes) { | ||
| 44 | + super.addAttributes(attributes); | ||
| 45 | + this.attributes.putAll(attributes); | ||
| 46 | + }; | ||
| 47 | + | ||
| 48 | + @Override | ||
| 49 | + public void addAttributes(String key, String value) { | ||
| 50 | + super.addAttributes(key, value); | ||
| 51 | + this.attributes.put(key, value); | ||
| 52 | + } | ||
| 53 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,66 @@ | |||
| 1 | + /* | ||
| 2 | + * Copyright 2024 Google LLC | ||
| 3 | + * | ||
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | + * you may not use this file except in compliance with the License. | ||
| 6 | + * You may obtain a copy of the License at | ||
| 7 | + * | ||
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | + * | ||
| 10 | + * Unless required by applicable law or agreed to in writing, software | ||
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | + * See the License for the specific language governing permissions and | ||
| 14 | + * limitations under the License. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | + package com.google.cloud.spanner; | ||
| 18 | + | ||
| 19 | + import com.google.api.core.BetaApi; | ||
| 20 | + import com.google.api.core.InternalApi; | ||
| 21 | + import com.google.api.gax.tracing.ApiTracer; | ||
| 22 | + import com.google.api.gax.tracing.ApiTracerFactory; | ||
| 23 | + import com.google.api.gax.tracing.MethodName; | ||
| 24 | + import com.google.api.gax.tracing.MetricsRecorder; | ||
| 25 | + import com.google.api.gax.tracing.MetricsTracer; | ||
| 26 | + import com.google.api.gax.tracing.MetricsTracerFactory; | ||
| 27 | + import com.google.api.gax.tracing.SpanName; | ||
| 28 | + import com.google.common.collect.ImmutableMap; | ||
| 29 | + import java.util.Map; | ||
| 30 | + | ||
| 31 | + /** | ||
| 32 | + * A {@link ApiTracerFactory} to build instances of {@link MetricsTracer}. | ||
| 33 | + * | ||
| 34 | + * <p>This class wraps the {@link MetricsRecorder} and pass it to {@link MetricsTracer}. It will be | ||
| 35 | + * used to record metrics in {@link MetricsTracer}. | ||
| 36 | + * | ||
| 37 | + * <p>This class is expected to be initialized once during client initialization. | ||
| 38 | + */ | ||
| 39 | + @BetaApi | ||
| 40 | + @InternalApi | ||
| 41 | + public class BuiltInMetricsTracerFactory extends MetricsTracerFactory { | ||
| 42 | + | ||
| 43 | + protected BuiltInMetricsRecorder builtInOpenTelemetryMetricsRecorder; | ||
| 44 | + private final Map<String, String> attributes; | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * Pass in a Map of client level attributes which will be added to every single MetricsTracer | ||
| 48 | + * created from the ApiTracerFactory. | ||
| 49 | + */ | ||
| 50 | + public BuiltInMetricsTracerFactory( | ||
| 51 | + BuiltInMetricsRecorder builtInOpenTelemetryMetricsRecorder, Map<String, String> attributes) { | ||
| 52 | + super(builtInOpenTelemetryMetricsRecorder, attributes); | ||
| 53 | + this.builtInOpenTelemetryMetricsRecorder = builtInOpenTelemetryMetricsRecorder; | ||
| 54 | + this.attributes = ImmutableMap.copyOf(attributes); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @Override | ||
| 58 | + public ApiTracer newTracer(ApiTracer parent, SpanName spanName, OperationType operationType) { | ||
| 59 | + BuiltInMetricsTracer metricsTracer = | ||
| 60 | + new BuiltInMetricsTracer( | ||
| 61 | + MethodName.of(spanName.getClientName(), spanName.getMethodName()), | ||
| 62 | + builtInOpenTelemetryMetricsRecorder); | ||
| 63 | + metricsTracer.addAttributes(attributes); | ||
| 64 | + return metricsTracer; | ||
| 65 | + } | ||
| 66 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,9 +20,9 @@ | |||
| 20 | 20 | import io.opentelemetry.sdk.metrics.export.MetricExporter; | |
| 21 | 21 | import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; | |
| 22 | 22 | ||
| 23 | - class BuiltInOpenTelemetryMetricsView { | ||
| 23 | + class BuiltInMetricsView { | ||
| 24 | 24 | ||
| 25 | - private BuiltInOpenTelemetryMetricsView() {} | ||
| 25 | + private BuiltInMetricsView() {} | ||
| 26 | 26 | ||
| 27 | 27 | /** Register built-in metrics on the {@link SdkMeterProviderBuilder} with credentials. */ | |
| 28 | 28 | static void registerBuiltinMetrics( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -190,4 +190,12 @@ public void addAttributes(Map<String, String> attributes) { | |||
| 190 | 190 | } | |
| 191 | 191 | } | |
| 192 | 192 | } | |
| 193 | + | ||
| 194 | + public void recordGFELatency(double latency) { | ||
| 195 | + for (ApiTracer child : children) { | ||
| 196 | + if (child instanceof BuiltInMetricsTracer) { | ||
| 197 | + ((BuiltInMetricsTracer) child).recordGFELatency(latency); | ||
| 198 | + } | ||
| 199 | + } | ||
| 200 | + } | ||
| 193 | 201 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -77,7 +77,8 @@ static List<TimeSeries> convertToSpannerTimeSeries(List<MetricData> collection) | |||
| 77 | 77 | ||
| 78 | 78 | for (MetricData metricData : collection) { | |
| 79 | 79 | // Get metrics data from GAX library and Spanner library | |
| 80 | - if (!(metricData.getInstrumentationScopeInfo().getName().equals(GAX_METER_NAME) || metricData.getInstrumentationScopeInfo().getName().equals(SPANNER_METER_NAME))) { | ||
| 80 | + if (!(metricData.getInstrumentationScopeInfo().getName().equals(GAX_METER_NAME) | ||
| 81 | + || metricData.getInstrumentationScopeInfo().getName().equals(SPANNER_METER_NAME))) { | ||
| 81 | 82 | // Filter out metric data for instruments that are not part of the spanner metrics list | |
| 82 | 83 | continue; | |
| 83 | 84 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments