diff --git a/README.md b/README.md index 16515506..1ff44801 100644 --- a/README.md +++ b/README.md @@ -48,4 +48,4 @@ See [Autoconfigure Readme](exporters/auto/README.md) for installation and usage [maven-image]: https://maven-badges.herokuapp.com/maven-central/com.google.cloud.opentelemetry/exporter-trace/badge.svg -[maven-url]: https://maven-badges.herokuapp.com/maven-central/com.google.cloud.opentelemetry/exporter-trace \ No newline at end of file +[maven-url]: https://maven-badges.herokuapp.com/maven-central/com.google.cloud.opentelemetry/exporter-trace diff --git a/build.gradle b/build.gradle index 1edfd04e..69edb7be 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,6 @@ ext.isReleaseVersion = !version.toString().endsWith("-SNAPSHOT") subprojects { apply plugin: 'jacoco' apply plugin: 'java-library' - apply plugin: 'maven' apply plugin: 'maven-publish' apply plugin: 'signing' apply plugin: 'com.diffplug.spotless' @@ -62,8 +61,8 @@ subprojects { group = "com.google.cloud.opentelemetry" // Note: Version now comes from nebula plugin - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 repositories { mavenCentral() @@ -104,10 +103,10 @@ subprojects { ext { assertjVersion = '3.22.0' autoServiceVersion = '1.0-rc7' - autoValueVersion = '1.7.4' + autoValueVersion = '1.10.1' slf4jVersion = '1.7.30' - googleCloudVersion = '2.0.5' - googleTraceVersion = '2.0.0' + googleCloudVersion = '2.8.28' + googleTraceVersion = '2.1.12' cloudMonitoringVersion = '3.0.0' openTelemetryVersion = '1.15.0' openTelemetryInstrumentationVersion = '1.14.0' @@ -119,18 +118,22 @@ subprojects { springWebVersion = '2.4.5' springOpenFeignVersion = '3.0.0' springOtelVersion = '1.0.0-M8' + cloudEventsCoreVersion = '2.4.0' + cloudFunctionsFrameworkApiVersion = '1.0.4' libraries = [ auto_service_annotations : "com.google.auto.service:auto-service-annotations:${autoServiceVersion}", auto_service : "com.google.auto.service:auto-service:${autoServiceVersion}", auto_value_annotations : "com.google.auto.value:auto-value-annotations:${autoValueVersion}", auto_value : "com.google.auto.value:auto-value:${autoValueVersion}", + cloudevents_core : "io.cloudevents:cloudevents-core:${cloudEventsCoreVersion}", google_cloud_core : "com.google.cloud:google-cloud-core:${googleCloudVersion}", google_cloud_trace : "com.google.cloud:google-cloud-trace:${googleTraceVersion}", - google_cloud_trace_grpc : "com.google.api.grpc:grpc-google-cloud-trace-v2:2.0.1", + google_cloud_trace_grpc : "com.google.api.grpc:grpc-google-cloud-trace-v2:${googleTraceVersion}", google_cloud_monitoring : "com.google.cloud:google-cloud-monitoring:${cloudMonitoringVersion}", google_cloud_monitoring_grpc : "com.google.cloud:grpc-google-cloud-monitoring-v3:${cloudMonitoringVersion}", google_cloud_pubsub : "com.google.cloud:google-cloud-pubsub:${pubSubVersion}", + google_cloud_functions_framework : "com.google.cloud.functions:functions-framework-api:${cloudFunctionsFrameworkApiVersion}", slf4j : "org.slf4j:slf4j-api:${slf4jVersion}", opentelemetry_api : "io.opentelemetry:opentelemetry-api:${openTelemetryVersion}", opentelemetry_context : "io.opentelemetry:opentelemetry-context:${openTelemetryVersion}", diff --git a/cloudbuild-e2e-cloud-functions-gen2.yaml b/cloudbuild-e2e-cloud-functions-gen2.yaml new file mode 100644 index 00000000..3d91a20b --- /dev/null +++ b/cloudbuild-e2e-cloud-functions-gen2.yaml @@ -0,0 +1,49 @@ +# Copyright 2022 Google +# +# 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. + +steps: + # Generate shadowJar for the instrumented test server + - name: "gradle:7.5.1-jdk11" + id: generate-jar + entrypoint: "gradle" + timeout: 4m + args: ["shadowJar"] + + # Zip the generated JAR file + - name: ubuntu + id: zip-jar + entrypoint: bash + args: + - '-c' + - | + apt-get update && \ + apt-get install zip --assume-yes && \ + cd e2e-test-server/build/libs && \ + zip function-source e2e-test-server-0.1.0-SNAPSHOT-all.jar + + # Run the test + - name: $_TEST_RUNNER_IMAGE + id: run-tests-cloudfunction + dir: / + env: ["PROJECT_ID=$PROJECT_ID"] + args: + - cloud-functions-gen2 + - --functionsource=/workspace/e2e-test-server/build/libs/function-source.zip + - --runtime=java11 + - --entrypoint=com.google.cloud.opentelemetry.endtoend.CloudFunctionHandler + +logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs +substitutions: + _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.16.0 + _TEST_SERVER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-java-e2e-test-server:${SHORT_SHA} diff --git a/cloudbuild-e2e-cloud-run.yaml b/cloudbuild-e2e-cloud-run.yaml new file mode 100644 index 00000000..495ba797 --- /dev/null +++ b/cloudbuild-e2e-cloud-run.yaml @@ -0,0 +1,37 @@ +# Copyright 2022 Google +# +# 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. + +steps: + # Wait for the image to exist + - name: "docker" + id: wait-for-image + entrypoint: "sh" + timeout: 3m + env: ["_TEST_SERVER_IMAGE=${_TEST_SERVER_IMAGE}"] + args: + - e2e-test-server/wait-for-image.sh + + # Run the test + - name: $_TEST_RUNNER_IMAGE + id: run-tests-cloudrun + dir: / + env: ["PROJECT_ID=$PROJECT_ID"] + args: + - cloud-run + - --image=$_TEST_SERVER_IMAGE + +logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs +substitutions: + _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.16.0 + _TEST_SERVER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-java-e2e-test-server:${SHORT_SHA} diff --git a/cloudbuild-e2e-gae.yaml b/cloudbuild-e2e-gae.yaml new file mode 100644 index 00000000..a0955cc6 --- /dev/null +++ b/cloudbuild-e2e-gae.yaml @@ -0,0 +1,38 @@ +# Copyright 2022 Google +# +# 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. + +steps: + # Wait for the image to exist + - name: "docker" + id: wait-for-image + entrypoint: "sh" + timeout: 3m + env: [ "_TEST_SERVER_IMAGE=${_TEST_SERVER_IMAGE}" ] + args: + - e2e-test-server/wait-for-image.sh + + # Run the test + - name: $_TEST_RUNNER_IMAGE + id: run-tests-gae + dir: / + env: [ "PROJECT_ID=$PROJECT_ID" ] + args: + - gae + - --image=$_TEST_SERVER_IMAGE + - --runtime=java11 + +logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs +substitutions: + _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.16.0 + _TEST_SERVER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-java-e2e-test-server:${SHORT_SHA} diff --git a/cloudbuild-e2e-gce.yaml b/cloudbuild-e2e-gce.yaml index f43afc51..db0ce214 100644 --- a/cloudbuild-e2e-gce.yaml +++ b/cloudbuild-e2e-gce.yaml @@ -33,5 +33,5 @@ steps: logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs substitutions: - _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.10.0 + _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.16.0 _TEST_SERVER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-java-e2e-test-server:${SHORT_SHA} diff --git a/cloudbuild-e2e-gke.yaml b/cloudbuild-e2e-gke.yaml index 6f5f6773..c0babd27 100644 --- a/cloudbuild-e2e-gke.yaml +++ b/cloudbuild-e2e-gke.yaml @@ -32,5 +32,5 @@ steps: logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs substitutions: - _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.10.0 + _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.16.0 _TEST_SERVER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-java-e2e-test-server:${SHORT_SHA} diff --git a/cloudbuild-e2e-local.yaml b/cloudbuild-e2e-local.yaml index a83d20a4..124a87a7 100644 --- a/cloudbuild-e2e-local.yaml +++ b/cloudbuild-e2e-local.yaml @@ -34,5 +34,5 @@ steps: logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs substitutions: - _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.10.0 + _TEST_RUNNER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-e2e-testing:0.16.0 _TEST_SERVER_IMAGE: gcr.io/${PROJECT_ID}/opentelemetry-operations-java-e2e-test-server:${SHORT_SHA} diff --git a/detectors/resources/src/main/java/com/google/cloud/opentelemetry/detectors/AttributesExtractorUtil.java b/detectors/resources/src/main/java/com/google/cloud/opentelemetry/detectors/AttributesExtractorUtil.java new file mode 100644 index 00000000..b4d9bd74 --- /dev/null +++ b/detectors/resources/src/main/java/com/google/cloud/opentelemetry/detectors/AttributesExtractorUtil.java @@ -0,0 +1,132 @@ +/* + * Copyright 2022 Google + * + * 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.detectors; + +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.semconv.resource.attributes.ResourceAttributes; + +/** + * A utility class that contains method that facilitate extraction of attributes from environment + * variables and metadata configurations. + * + *
This class only adds helper methods to extract {@link ResourceAttributes} that are common + * across all the supported compute environments. + */ +public class AttributesExtractorUtil { + + /** + * Utility method to extract cloud availability zone from passed {@link GCPMetadataConfig}. The + * method modifies the passed attributesBuilder by adding the extracted property to it. If the + * zone cannot be found, calling this method has no effect. + * + *
Example zone: australia-southeast1-a + * + * @param attributesBuilder The {@link AttributesBuilder} to which the extracted property needs to + * be added. + * @param metadataConfig The {@link GCPMetadataConfig} from which the cloud availability zone + * value is extracted. + */ + public static void addAvailabilityZoneFromMetadata( + AttributesBuilder attributesBuilder, GCPMetadataConfig metadataConfig) { + String zone = metadataConfig.getZone(); + if (zone != null) { + attributesBuilder.put(ResourceAttributes.CLOUD_AVAILABILITY_ZONE, zone); + } + } + + /** + * Utility method to extract the cloud region from passed {@link GCPMetadataConfig}. The method + * modifies the passed attributesBuilder by adding the extracted property to it. + * + *
Example region: australia-southeast1 + * + * @param attributesBuilder The {@link AttributesBuilder} to which the extracted property needs to + * be added. + * @param metadataConfig The {@link GCPMetadataConfig} from which the cloud region value is + * extracted. + */ + public static void addCloudRegionFromMetadataUsingZone( + AttributesBuilder attributesBuilder, GCPMetadataConfig metadataConfig) { + String zone = metadataConfig.getZone(); + if (zone != null) { + // Parsing required to scope up to a region + String[] splitArr = zone.split("-"); + if (splitArr.length > 2) { + attributesBuilder.put(ResourceAttributes.CLOUD_REGION, splitArr[0] + "-" + splitArr[1]); + } + } + } + + /** + * Utility method to extract the cloud region from passed {@link GCPMetadataConfig}. The method + * modifies the passed attributesBuilder by adding the extracted property to it. + * + *
Example region: australia-southeast1 + * + * @param attributesBuilder The {@link AttributesBuilder} to which the extracted property needs to + * be added. + * @param metadataConfig The {@link GCPMetadataConfig} from which the cloud region value is + * extracted. + */ + public static void addCloudRegionFromMetadataUsingRegion( + AttributesBuilder attributesBuilder, GCPMetadataConfig metadataConfig) { + String region = metadataConfig.getRegion(); + if (region != null) { + attributesBuilder.put(ResourceAttributes.CLOUD_REGION, region); + } + } + + /** + * Utility method to extract the current compute instance ID from the passed {@link + * GCPMetadataConfig}. The method modifies the passed attributesBuilder by adding the extracted + * property to it. + * + *
This kind of {@link PubSubServer} works well with Google Cloud's non-serverless compute + * offerings like GCE and GKE. This server should be avoided for running tests in serverless + * environments like CloudRun. + * + *
This class is responsible for the following: + * + *
Google cloud's serverless offerings like CloudRun recommend using 'push' mode instead of + * 'pull' for subscriptions in pub/sub since CloudRun requires running code (the instance spun up is + * like a daemon when no request is processing). This means we need a dedicated server actively + * listening on a port instead of waiting on messages being pushed to a topic which can then be + * pulled (this is what happens in 'pull' subscription mode). This server sets up an {@link + * HttpServer} on a specified port which actively listens for incoming requests. + * + *
More information on why 'push' mode is preferred can be seen here. + * + *
This class is responsible for the following: + * + *
It is responsible for the following: * *
This class includes a main method which runs the integration test driver using locally
- * available credentials to acccess pubsub channels.
+ * available credentials to access pubsub channels.
*/
-public class Server implements AutoCloseable {
- private final ScenarioHandlerManager scenarioHandlers = new ScenarioHandlerManager();
+public class Server implements PubSubMessageHandler {
+
+ private final ScenarioHandlerManager scenarioHandlers;
private final Publisher publisher;
- private final Subscriber subscriber;
public Server() throws Exception {
+ this.scenarioHandlers = new ScenarioHandlerManager();
this.publisher = Publisher.newBuilder(Constants.getResponseTopic()).build();
- this.subscriber =
- Subscriber.newBuilder(Constants.getRequestSubscription(), this::handleMessage).build();
- subscriber.addListener(
- new Subscriber.Listener() {
- @Override
- public void failed(Subscriber.State from, Throwable failure) {
- // Handle failure. This is called when the Subscriber encountered a fatal error and is
- // shutting down.
- System.err.println(failure);
- }
- },
- MoreExecutors.directExecutor());
}
- /** Starts the subcriber pulling requests. */
- public void start() {
- subscriber.startAsync().awaitRunning();
- }
+ @Override
+ public PubSubMessageResponse handlePubSubMessage(PubsubMessage message) {
+ if (!message.containsAttributes(Constants.TEST_ID)) {
+ return PubSubMessageResponse.NACK;
+ }
+ String testId = message.getAttributesOrDefault(Constants.TEST_ID, "");
+ if (!message.containsAttributes(Constants.SCENARIO)) {
+ respond(
+ testId,
+ Response.invalidArgument(
+ String.format("Expected attribute \"%s\" is missing", Constants.SCENARIO)));
+ return PubSubMessageResponse.ACK;
+ }
+ String scenario = message.getAttributesOrDefault(Constants.SCENARIO, "");
+ Request request = Request.make(testId, message.getAttributesMap(), message.getData());
- /** Closes our subscriptions. */
- public void close() {
- if (subscriber != null) {
- subscriber.stopAsync();
- subscriber.awaitTerminated();
+ // Run the given request/response cycle through a handler and respond with results.
+ Response response = Response.EMPTY;
+ try {
+ response = scenarioHandlers.handleScenario(scenario, request);
+ } catch (Throwable e) {
+ e.printStackTrace(System.err);
+ response = Response.internalError(e);
+ } finally {
+ respond(testId, response);
}
+ return PubSubMessageResponse.ACK;
+ }
+
+ /**
+ * This method is responsible for doing any cleanup tasks required for the {@link
+ * PubSubMessageHandler} when handler is no longer required.
+ */
+ @Override
+ public void cleanupMessageHandler() {
if (publisher != null) {
publisher.shutdown();
}
}
/** This method converts from {@link Response} to pubsub and sends out the publisher channel. */
- public void respond(final String testId, final Response response) {
+ private void respond(final String testId, final Response response) {
final PubsubMessage message =
PubsubMessage.newBuilder()
.putAllAttributes(response.headers())
@@ -93,50 +105,33 @@ public void respond(final String testId, final Response response) {
public void onSuccess(String messageId) {}
public void onFailure(Throwable t) {
- System.out.println("failed to publish response to test: " + testId);
t.printStackTrace();
}
},
MoreExecutors.directExecutor());
- }
-
- /** Execute a scenario based on the incoming message from the test runner. */
- public void handleMessage(PubsubMessage message, AckReplyConsumer consumer) {
- if (!message.containsAttributes(Constants.TEST_ID)) {
- consumer.nack();
- return;
- }
- String testId = message.getAttributesOrDefault(Constants.TEST_ID, "");
- if (!message.containsAttributes(Constants.SCENARIO)) {
- respond(
- testId,
- Response.invalidArgument(
- String.format("Expected attribute \"%s\" is missing", Constants.SCENARIO)));
- consumer.ack();
- return;
+ try {
+ // Wait for the future to get completed.
+ // This prevents cloud functions from exiting too quickly
+ messageIdFuture.get(30, TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ e.printStackTrace();
}
- String scenario = message.getAttributesOrDefault(Constants.SCENARIO, "");
- Request request = Request.make(testId, message.getAttributesMap(), message.getData());
+ }
- // Run the given request/response cycle through a handler and respond with results.
- Response response = Response.EMPTY;
- try {
- response = scenarioHandlers.handleScenario(scenario, request);
- } catch (Throwable e) {
- e.printStackTrace(System.err);
- response = Response.internalError(e);
- } finally {
- respond(testId, response);
- consumer.ack();
+ private static PubSubServer createPubSubServer(Server server) {
+ if (Constants.SUBSCRIPTION_MODE.equals(Constants.SUBSCRIPTION_MODE_PULL)) {
+ return new PubSubPullServer(server);
}
+ return new PubSubPushServer(Integer.parseInt(Constants.PUSH_PORT), server);
}
/** Runs our server. */
public static void main(String[] args) throws Exception {
- try (Server server = new Server()) {
- server.start();
- // Docs for Subscriber recommend doing this to block main thread while daemon thread consumes
- // stuff.
+ Server server = new Server();
+ try (PubSubServer pubSubServer = createPubSubServer(server)) {
+ pubSubServer.start();
+ // Docs for Subscriber recommend doing this to block main thread while daemon thread
+ // consumes stuff.
for (; ; ) {
Thread.sleep(Long.MAX_VALUE);
}
diff --git a/e2e.Dockerfile b/e2e.Dockerfile
index f0e77767..898bfb2a 100644
--- a/e2e.Dockerfile
+++ b/e2e.Dockerfile
@@ -14,7 +14,7 @@
# limitations under the License.
# Build relative to root of repository i.e. `docker build --file e2e.Dockerfile --tag=$tag ..`
-FROM gradle:6.9-jdk11-hotspot as builder
+FROM gradle:7.5.1-jdk11 as builder
COPY --chown=gradle:gradle . /app/src
WORKDIR /app/src
diff --git a/examples/autoconf/build.gradle b/examples/autoconf/build.gradle
index 488b2fd9..94aba213 100644
--- a/examples/autoconf/build.gradle
+++ b/examples/autoconf/build.gradle
@@ -23,8 +23,8 @@ plugins {
description = 'Examples for using java autoconfiguration and Google Cloud Operations'
dependencies {
- compile(libraries.opentelemetry_api)
- compile(libraries.opentelemetry_sdk_metrics)
+ implementation(libraries.opentelemetry_api)
+ implementation(libraries.opentelemetry_sdk_metrics)
runtimeOnly(libraries.opentelemetry_sdk_autoconf)
runtimeOnly(libraries.opentelemetry_sdk)
runtimeOnly project(':exporter-auto')
diff --git a/examples/metrics/build.gradle b/examples/metrics/build.gradle
index 10a71674..f225721b 100644
--- a/examples/metrics/build.gradle
+++ b/examples/metrics/build.gradle
@@ -31,9 +31,9 @@ mainClassName = 'com.google.cloud.opentelemetry.example.metrics.MetricsExporterE
description = 'Examples for Cloud Monitoring Exporter'
dependencies {
- compile(libraries.opentelemetry_api)
- compile(libraries.opentelemetry_sdk_metrics)
- compile(libraries.google_cloud_monitoring)
- compile project(':exporter-metrics')
+ implementation(libraries.opentelemetry_api)
+ implementation(libraries.opentelemetry_sdk_metrics)
+ implementation(libraries.google_cloud_monitoring)
+ implementation project(':exporter-metrics')
runtimeOnly project(':detector-resources')
}
diff --git a/examples/resource/build.gradle b/examples/resource/build.gradle
index dfc84be4..735802d0 100644
--- a/examples/resource/build.gradle
+++ b/examples/resource/build.gradle
@@ -23,9 +23,9 @@ plugins {
description = 'Examples for showing resource detection in various GCP environments.'
dependencies {
- compile project(':detector-resources')
- compile(libraries.opentelemetry_sdk_autoconf)
- compile(libraries.opentelemetry_sdk_resources)
+ implementation project(':detector-resources')
+ implementation(libraries.opentelemetry_sdk_autoconf)
+ implementation(libraries.opentelemetry_sdk_resources)
}
mainClassName = 'com.google.cloud.opentelemetry.example.resource.ResourceExample'
diff --git a/examples/resource/src/main/java/com/google/cloud/opentelemetry/example/resource/ResourceExample.java b/examples/resource/src/main/java/com/google/cloud/opentelemetry/example/resource/ResourceExample.java
index 3580d929..d11f765f 100644
--- a/examples/resource/src/main/java/com/google/cloud/opentelemetry/example/resource/ResourceExample.java
+++ b/examples/resource/src/main/java/com/google/cloud/opentelemetry/example/resource/ResourceExample.java
@@ -15,7 +15,7 @@
*/
package com.google.cloud.opentelemetry.example.resource;
-import com.google.cloud.opentelemetry.detectors.GKEResource;
+import com.google.cloud.opentelemetry.detectors.GCPResource;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
public class ResourceExample {
@@ -29,7 +29,7 @@ public static void main(String[] args) {
.getResource();
System.out.println(autoResource.getAttributes());
System.out.println("Detecting resource: hardcoded");
- GKEResource resource = new GKEResource();
+ GCPResource resource = new GCPResource();
System.out.println(resource.getAttributes());
}
}
diff --git a/examples/trace/build.gradle b/examples/trace/build.gradle
index 8d2e069a..75e5f1ab 100644
--- a/examples/trace/build.gradle
+++ b/examples/trace/build.gradle
@@ -24,10 +24,10 @@ mainClassName = 'com.google.cloud.opentelemetry.example.trace.TraceExporterExamp
description = 'Examples for Cloud Trace Exporter'
dependencies {
- compile(libraries.opentelemetry_api)
- compile(libraries.opentelemetry_sdk)
- compile(libraries.google_cloud_trace)
- compile project(':exporter-trace')
+ implementation(libraries.opentelemetry_api)
+ implementation(libraries.opentelemetry_sdk)
+ implementation(libraries.google_cloud_trace)
+ implementation project(':exporter-trace')
runtimeOnly project(':detector-resources')
}
diff --git a/exporters/auto/build.gradle b/exporters/auto/build.gradle
index 0a740d26..b32fc695 100644
--- a/exporters/auto/build.gradle
+++ b/exporters/auto/build.gradle
@@ -44,6 +44,7 @@ dependencies {
shadowJar{
classifier = null
+ mergeServiceFiles()
}
publishing {
diff --git a/exporters/metrics/README.md b/exporters/metrics/README.md
index e135b6a8..45f65138 100644
--- a/exporters/metrics/README.md
+++ b/exporters/metrics/README.md
@@ -61,7 +61,7 @@ MeterProvider provider = SdkMeterProvider.builder()
// Rate at which data can be written to a single time series: one point each 10
// seconds.
PeriodicMetricReader.builder(metricExporter)
- .setImterval(java.time.Duration.ofSeconds(20))
+ .setInterval(java.time.Duration.ofSeconds(20))
.build())
.build();
```
@@ -70,10 +70,10 @@ MeterProvider provider = SdkMeterProvider.builder()
| ------------- | -------------------- | ------------ | ----------- | ------- |
| projectId | GOOGLE_CLOUD_PROJECT or GOOGLE_APPLICATION_CREDENTIALS | ??? | The cloud project id. This is autodiscovered. | The autodiscovered value. |
| credentials | GOOGLE_APPLICATION_CREDENTIALS | N/A | Credentials to use when talking to Cloud Monitoring API. | App Engine, Cloud Shell, GCE built-in or provided by `gcloud auth application-default login` |
-| deadline | ??? | ??? | The deadline limit on export calls to Cloud Monitoring API | 10 seconds |
+| deadline | ??? | ??? | The deadline limit on export calls to Cloud Monitoring API | 12 seconds |
| metricDescriptorStrategy | ??? | ??? | How to adapt OpenTelemetry metric definition into google cloud. `ALWAYS_SEND` will try to create metric descriptors on every export. `SEND_ONCE` will try to create metric descriptors once per Java instance/classloader. `NEVER_SEND` will rely on Cloud Monitoring's auto-generated MetricDescriptors from time series. | `SEND_ONCE` |
[maven-image]: https://maven-badges.herokuapp.com/maven-central/com.google.cloud.opentelemetry/exporter-metrics/badge.svg
-[maven-url]: https://maven-badges.herokuapp.com/maven-central/com.google.cloud.opentelemetry/exporter-metrics
\ No newline at end of file
+[maven-url]: https://maven-badges.herokuapp.com/maven-central/com.google.cloud.opentelemetry/exporter-metrics
diff --git a/exporters/metrics/src/main/java/com/google/cloud/opentelemetry/metric/AggregateByLabelMetricTimeSeriesBuilder.java b/exporters/metrics/src/main/java/com/google/cloud/opentelemetry/metric/AggregateByLabelMetricTimeSeriesBuilder.java
index 0d05ac65..6a858bca 100644
--- a/exporters/metrics/src/main/java/com/google/cloud/opentelemetry/metric/AggregateByLabelMetricTimeSeriesBuilder.java
+++ b/exporters/metrics/src/main/java/com/google/cloud/opentelemetry/metric/AggregateByLabelMetricTimeSeriesBuilder.java
@@ -45,14 +45,16 @@ public final class AggregateByLabelMetricTimeSeriesBuilder implements MetricTime
private final Map Defaults to workload.googleapis.com.
+ * @return the prefix to attach to metrics.
+ */
+ public abstract String getPrefix();
+
/**
* Returns the deadline for exporting to Cloud Monitoring backend.
*
- * Default value is 10 seconds.
+ * Default value is {{@link MetricConfiguration#DEFAULT_DEADLINE}.
*
* @return the export deadline.
*/
@@ -105,6 +117,7 @@ public abstract class MetricConfiguration {
public static Builder builder() {
return new AutoValue_MetricConfiguration.Builder()
.setProjectId(DEFAULT_PROJECT_ID)
+ .setPrefix(DEFAULT_PREFIX)
.setDeadline(DEFAULT_DEADLINE)
.setDescriptorStrategy(MetricDescriptorStrategy.SEND_ONCE)
.setInsecureEndpoint(false)
@@ -124,6 +137,9 @@ public abstract static class Builder {
/** Set the GCP project where metrics should be writtten. */
public abstract Builder setProjectId(String projectId);
+ /** Set the prefix prepended to metric names. */
+ public abstract Builder setPrefix(String prefix);
+
/** Set the credentials to use when writing metrics. */
public abstract Builder setCredentials(Credentials newCredentials);
diff --git a/exporters/metrics/src/main/java/com/google/cloud/opentelemetry/metric/MetricTranslator.java b/exporters/metrics/src/main/java/com/google/cloud/opentelemetry/metric/MetricTranslator.java
index 00af9eb8..08a51c5b 100644
--- a/exporters/metrics/src/main/java/com/google/cloud/opentelemetry/metric/MetricTranslator.java
+++ b/exporters/metrics/src/main/java/com/google/cloud/opentelemetry/metric/MetricTranslator.java
@@ -37,6 +37,7 @@
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.data.MetricDataType;
import io.opentelemetry.sdk.metrics.data.SumData;
+import java.nio.file.Paths;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@@ -48,7 +49,6 @@ public final class MetricTranslator {
private static final Logger logger = LoggerFactory.getLogger(MetricTranslator.class);
- static final String DESCRIPTOR_TYPE_URL = "workload.googleapis.com/";
static final Set