Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,12 @@ public static boolean isReady() {
}
}

@InternalApi
@Override
public StorageClientMetrics getStorageClientMetrics() {
return super.getStorageClientMetrics();
}

private static class ReadObjectRangeResultRetryAlgorithmDecorator
extends BasicResultRetryAlgorithm<Object> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,5 +551,10 @@ public RetrySettings getRetrySettings() {
public ApiClock getClock() {
return HttpStorageOptions.this.getClock();
}

@Override
public @Nullable StorageClientMetrics getStorageClientMetrics() {
return HttpStorageOptions.this.getStorageClientMetrics();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
import io.grpc.ManagedChannelBuilder;
import io.grpc.opentelemetry.GrpcOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
Expand Down Expand Up @@ -209,6 +210,119 @@ static String getCloudMonitoringEndpoint(String endpoint, String universeDomain)
return metricServiceEndpoint + ":" + endpoint.split(":")[1];
}

@Nullable
private static HostAndPort parseHostAndPort(@Nullable String host) {
if (host == null || host.trim().isEmpty()) {
return null;
}
String s = host.trim();
if (s.startsWith("google-c2p:///")) {
s = s.substring("google-c2p:///".length());
} else if (s.startsWith("https://")) {
s = s.substring("https://".length());
} else if (s.startsWith("http://")) {
s = s.substring("http://".length());
}
int slashIdx = s.indexOf('/');
if (slashIdx >= 0) {
s = s.substring(0, slashIdx);
}
if (s.isEmpty()) {
return null;
}
return HostAndPort.fromString(s);
}

static String formatStorageEndpoint(@Nullable String host) {
HostAndPort parsed = parseHostAndPort(host);
if (parsed == null) {
return "storage.googleapis.com:443";
}
return parsed.withDefaultPort(443).toString();
}

@Nullable
static String extractServerAddress(@Nullable String host) {
HostAndPort parsed = parseHostAndPort(host);
return parsed != null ? parsed.getHost() : null;
}

@Nullable
static SdkMeterProvider createDefaultClientMeterProvider(
@Nullable String host,
@Nullable String configuredProjectId,
@Nullable String universeDomain,
@Nullable Duration metricInterval,
String api) {
try {
GCPResourceProvider resourceProvider = new GCPResourceProvider();
Attributes detectedAttributes = resourceProvider.getAttributes();
return createDefaultClientMeterProvider(
host, configuredProjectId, universeDomain, metricInterval, api, detectedAttributes);
} catch (Exception e) {
log.warning("Failed to create default client MeterProvider: " + e.getMessage());
return null;
}
}

@VisibleForTesting
@Nullable
static SdkMeterProvider createDefaultClientMeterProvider(
@Nullable String host,
@Nullable String configuredProjectId,
@Nullable String universeDomain,
@Nullable Duration metricInterval,
String api,
Attributes detectedAttributes) {
try {
@Nullable String detectedProjectId =
detectedAttributes.get(AttributeKey.stringKey("cloud.account.id"));
if (detectedProjectId != null && detectedProjectId.trim().isEmpty()) {
detectedProjectId = null;
}
@Nullable String cleanConfiguredProjectId =
(configuredProjectId != null && !configuredProjectId.trim().isEmpty())
? configuredProjectId.trim()
: null;
if (cleanConfiguredProjectId == null && detectedProjectId == null) {
log.warning(
"Unable to determine the Project ID in order to report metrics. No storage client"
+ " metrics will be reported.");
return null;
}
String projectIdToUse =
detectedProjectId != null ? detectedProjectId : cleanConfiguredProjectId;
if (!projectIdToUse.equals(cleanConfiguredProjectId)) {
log.warning(
"The Project ID configured for storage client metrics is "
+ projectIdToUse
+ ", but the Project ID of the storage client is "
+ cleanConfiguredProjectId
+ ". Make sure that the service account in use has the required metric writing"
+ " role (roles/monitoring.metricWriter) in the project "
+ projectIdToUse
+ ", or metrics will not be written.");
}
Attributes attributesToUse =
Attributes.builder()
.putAll(detectedAttributes)
.put(AttributeKey.stringKey("cloud.account.id"), projectIdToUse)
.build();
String formattedEndpoint = formatStorageEndpoint(host);
String metricServiceEndpoint = getCloudMonitoringEndpoint(formattedEndpoint, universeDomain);
return createClientMeterProvider(
metricServiceEndpoint,
projectIdToUse,
attributesToUse,
metricInterval,
/* shouldSuppressExceptions= */ true,
api);
} catch (Exception e) {
log.warning("Failed to create default client MeterProvider: " + e.getMessage());
return null;
}
}

static final ImmutableList<String> CLIENT_LATENCY_HISTOGRAMS =
ImmutableList.of(
StorageClientMetrics.METRIC_RPC_CLIENT_CALL_DURATION,
Expand Down
Loading
Loading