From 7bb4729c285504a775205ac0f178459e707d5f42 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Tue, 17 Sep 2024 19:07:53 +0000 Subject: [PATCH 1/4] update sample to wait for shutdown --- .../example/metrics/MetricsExporterExample.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/examples/metrics/src/main/java/com/google/cloud/opentelemetry/example/metrics/MetricsExporterExample.java b/examples/metrics/src/main/java/com/google/cloud/opentelemetry/example/metrics/MetricsExporterExample.java index fd463f03..a97df0f0 100644 --- a/examples/metrics/src/main/java/com/google/cloud/opentelemetry/example/metrics/MetricsExporterExample.java +++ b/examples/metrics/src/main/java/com/google/cloud/opentelemetry/example/metrics/MetricsExporterExample.java @@ -30,6 +30,7 @@ import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.contrib.gcp.resource.GCPResourceProvider; import io.opentelemetry.exporter.logging.LoggingMetricExporter; +import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; @@ -37,6 +38,7 @@ import java.io.IOException; import java.time.Duration; import java.util.Random; +import java.util.concurrent.TimeUnit; public class MetricsExporterExample { private static SdkMeterProvider METER_PROVIDER; @@ -146,9 +148,16 @@ public static void main(String[] args) throws InterruptedException, IOException } finally { System.out.println("Shutting down the metrics-example application"); - METER_PROVIDER.shutdown(); + CompletableResultCode resultCode = METER_PROVIDER.shutdown(); + // Wait upto 60 seconds for job to complete + resultCode.join(60, TimeUnit.SECONDS); + if (resultCode.isSuccess()) { + System.out.println("Shutdown completed successfully!"); + } else { + System.out.println("Unable to shutdown gracefully!"); + } - System.out.println("Shutdown complete"); + System.out.println("Exiting job"); } } } From 5ac612387c21c6393b866db20a24596063378799 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 18 Sep 2024 03:06:22 +0000 Subject: [PATCH 2/4] Add support for detecting Cloud Run Job --- .../detection/AttributeKeys.java | 4 ++ .../detection/GCPPlatformDetector.java | 9 ++- .../detection/GoogleCloudRunJob.java | 58 +++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/GoogleCloudRunJob.java diff --git a/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/AttributeKeys.java b/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/AttributeKeys.java index c7a45ac8..3ea75c40 100644 --- a/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/AttributeKeys.java +++ b/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/AttributeKeys.java @@ -52,6 +52,10 @@ public final class AttributeKeys { public static final String SERVERLESS_COMPUTE_CLOUD_REGION = AttributeKeys.CLOUD_REGION; public static final String SERVERLESS_COMPUTE_INSTANCE_ID = AttributeKeys.INSTANCE_ID; + // Cloud Run Job Specific Attributes + public static final String GCR_JOB_EXECUTION_KEY = "gcr_job_execution_key"; + public static final String GCR_JOB_TASK_INDEX = "gcr_job_task_index"; + static final String AVAILABILITY_ZONE = "availability_zone"; static final String CLOUD_REGION = "cloud_region"; static final String INSTANCE_ID = "instance_id"; diff --git a/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetector.java b/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetector.java index 414f9b56..78e10820 100644 --- a/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetector.java +++ b/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetector.java @@ -53,6 +53,8 @@ private SupportedPlatform detectSupportedPlatform() { return SupportedPlatform.GOOGLE_CLOUD_RUN; } else if (environmentVariables.get("FUNCTION_TARGET") != null) { return SupportedPlatform.GOOGLE_CLOUD_FUNCTIONS; + } else if (environmentVariables.get("CLOUD_RUN_JOB") != null) { + return SupportedPlatform.GOOGLE_CLOUD_RUN_JOB; } else if (environmentVariables.get("GAE_SERVICE") != null) { return SupportedPlatform.GOOGLE_APP_ENGINE; } @@ -75,6 +77,9 @@ private DetectedPlatform generateDetectedPlatform(SupportedPlatform platform) { case GOOGLE_CLOUD_FUNCTIONS: detectedPlatform = new GoogleCloudFunction(environmentVariables, metadataConfig); break; + case GOOGLE_CLOUD_RUN_JOB: + detectedPlatform = new GoogleCloudRunJob(environmentVariables, metadataConfig); + break; case GOOGLE_APP_ENGINE: detectedPlatform = new GoogleAppEngine(environmentVariables, metadataConfig); break; @@ -98,8 +103,10 @@ public enum SupportedPlatform { GOOGLE_KUBERNETES_ENGINE, /** Represents the Google App Engine platform. Could either be flex or standard. */ GOOGLE_APP_ENGINE, - /** Represents the Google Cloud Run platform. */ + /** Represents the Google Cloud Run platform (Service). */ GOOGLE_CLOUD_RUN, + /** Represents the Google Cloud Run platform (Jobs). */ + GOOGLE_CLOUD_RUN_JOB, /** Represents the Google Cloud Functions platform. */ GOOGLE_CLOUD_FUNCTIONS, /** Represents the case when the application is not running on GCP. */ diff --git a/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/GoogleCloudRunJob.java b/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/GoogleCloudRunJob.java new file mode 100644 index 00000000..08f6a4a7 --- /dev/null +++ b/detectors/resources-support/src/main/java/com/google/cloud/opentelemetry/detection/GoogleCloudRunJob.java @@ -0,0 +1,58 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed 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 com.google.cloud.opentelemetry.detection; + +import java.util.HashMap; +import java.util.Map; + +final class GoogleCloudRunJob implements DetectedPlatform { + private final GCPMetadataConfig metadataConfig; + private final EnvironmentVariables environmentVariables; + private final Map availableAttributes; + + GoogleCloudRunJob(EnvironmentVariables environmentVariables, GCPMetadataConfig metadataConfig) { + this.metadataConfig = metadataConfig; + this.environmentVariables = environmentVariables; + this.availableAttributes = prepareAttributes(); + } + + private Map prepareAttributes() { + Map map = new HashMap<>(); + map.put(AttributeKeys.SERVERLESS_COMPUTE_NAME, this.environmentVariables.get("CLOUD_RUN_JOB")); + map.put( + AttributeKeys.GCR_JOB_EXECUTION_KEY, this.environmentVariables.get("CLOUD_RUN_EXECUTION")); + map.put( + AttributeKeys.GCR_JOB_TASK_INDEX, this.environmentVariables.get("CLOUD_RUN_TASK_INDEX")); + map.put(AttributeKeys.SERVERLESS_COMPUTE_INSTANCE_ID, this.metadataConfig.getInstanceId()); + map.put(AttributeKeys.SERVERLESS_COMPUTE_CLOUD_REGION, this.metadataConfig.getRegionFromZone()); + return map; + } + + @Override + public GCPPlatformDetector.SupportedPlatform getSupportedPlatform() { + return GCPPlatformDetector.SupportedPlatform.GOOGLE_CLOUD_RUN_JOB; + } + + @Override + public String getProjectId() { + return metadataConfig.getProjectId(); + } + + @Override + public Map getAttributes() { + return this.availableAttributes; + } +} From add45dcc2025685da990038b8c104c8845387397 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 18 Sep 2024 16:35:54 +0000 Subject: [PATCH 3/4] Add tests for Google Cloud Run Job --- .../detection/GCPPlatformDetectorTest.java | 60 ++++++++++++++----- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/detectors/resources-support/src/test/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetectorTest.java b/detectors/resources-support/src/test/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetectorTest.java index 57200eee..5ec83405 100644 --- a/detectors/resources-support/src/test/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetectorTest.java +++ b/detectors/resources-support/src/test/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetectorTest.java @@ -15,19 +15,7 @@ */ package com.google.cloud.opentelemetry.detection; -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static com.google.cloud.opentelemetry.detection.AttributeKeys.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - import com.github.tomakehurst.wiremock.junit5.WireMockTest; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -37,6 +25,19 @@ import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mockito; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.google.cloud.opentelemetry.detection.AttributeKeys.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + @WireMockTest(httpPort = 8089) public class GCPPlatformDetectorTest { private final GCPMetadataConfig mockMetadataConfig = @@ -274,10 +275,10 @@ public void testGCFDetectionWhenGCRAttributesPresent() { detector.detectPlatform().getAttributes()); } - /** Google Cloud Run Tests * */ + /** Google Cloud Run Tests (Service) * */ @Test public void testGCFResourceWithCloudRunAttributesSucceeds() { - // Setup GCR required env vars + // Setup GCR service required env vars envVars.put("K_SERVICE", "cloud-run-hello"); envVars.put("K_REVISION", "cloud-run-hello.1"); envVars.put("K_CONFIGURATION", "cloud-run-hello"); @@ -306,6 +307,37 @@ public void testGCFResourceWithCloudRunAttributesSucceeds() { assertEquals("GCR-instance-id", detectedAttributes.get(SERVERLESS_COMPUTE_INSTANCE_ID)); } + /** Google Cloud Run Tests (Jobs) * */ + @Test + public void testCloudRunJobResourceWithAttributesSucceeds() { + // Setup GCR Job required env vars + envVars.put("CLOUD_RUN_JOB", "cloud-run-hello-job"); + envVars.put("CLOUD_RUN_EXECUTION", "cloud-run-hello-job-1a2b3c"); + envVars.put("CLOUD_RUN_TASK_INDEX", "0"); + + TestUtils.stubEndpoint("/project/project-id", "GCR-pid"); + TestUtils.stubEndpoint("/instance/zone", "country-region-zone"); + TestUtils.stubEndpoint("/instance/id", "GCR-job-instance-id"); + + EnvironmentVariables mockEnv = new EnvVarMock(envVars); + GCPPlatformDetector detector = new GCPPlatformDetector(mockMetadataConfig, mockEnv); + + Map detectedAttributes = detector.detectPlatform().getAttributes(); + assertEquals( + GCPPlatformDetector.SupportedPlatform.GOOGLE_CLOUD_RUN_JOB, + detector.detectPlatform().getSupportedPlatform()); + assertEquals( + new GoogleCloudRunJob(mockEnv, mockMetadataConfig).getAttributes(), detectedAttributes); + assertEquals("GCR-pid", detector.detectPlatform().getProjectId()); + assertEquals(5, detectedAttributes.size()); + + assertEquals("cloud-run-hello-job-1a2b3c", detectedAttributes.get(GCR_JOB_EXECUTION_KEY)); + assertEquals("0", detectedAttributes.get(GCR_JOB_TASK_INDEX)); + assertEquals("cloud-run-hello-job", detectedAttributes.get(SERVERLESS_COMPUTE_NAME)); + assertEquals("country-region", detectedAttributes.get(SERVERLESS_COMPUTE_CLOUD_REGION)); + assertEquals("GCR-job-instance-id", detectedAttributes.get(SERVERLESS_COMPUTE_INSTANCE_ID)); + } + /** Google App Engine Tests * */ @ParameterizedTest @MethodSource("provideGAEVariantEnvironmentVariable") From 3b45382e2cb5e89f3e24b195cd96d617685e5baa Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 18 Sep 2024 19:25:11 +0000 Subject: [PATCH 4/4] Style fix --- .../detection/GCPPlatformDetectorTest.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/detectors/resources-support/src/test/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetectorTest.java b/detectors/resources-support/src/test/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetectorTest.java index 5ec83405..2cdaf112 100644 --- a/detectors/resources-support/src/test/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetectorTest.java +++ b/detectors/resources-support/src/test/java/com/google/cloud/opentelemetry/detection/GCPPlatformDetectorTest.java @@ -15,7 +15,19 @@ */ package com.google.cloud.opentelemetry.detection; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static com.google.cloud.opentelemetry.detection.AttributeKeys.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + import com.github.tomakehurst.wiremock.junit5.WireMockTest; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -25,19 +37,6 @@ import org.junit.jupiter.params.provider.ValueSource; import org.mockito.Mockito; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.Stream; - -import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; -import static com.github.tomakehurst.wiremock.client.WireMock.get; -import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; -import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; -import static com.google.cloud.opentelemetry.detection.AttributeKeys.*; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - @WireMockTest(httpPort = 8089) public class GCPPlatformDetectorTest { private final GCPMetadataConfig mockMetadataConfig =