Skip to content

Commit cb785c8

Browse files
dashpolepsx95
andauthored
Add otlp metric example with gcp auth (#388)
* add otlp metric example with gcp auth * Fix sample build --------- Co-authored-by: Pranav Sharma <sharmapranav@google.com>
1 parent 3e84946 commit cb785c8

4 files changed

Lines changed: 204 additions & 0 deletions

File tree

examples/otlpmetric/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# OTLP Metric with Google Auth Example
2+
3+
Run this sample to connect to an endpoint that is protected by GCP authentication.
4+
5+
First, get GCP credentials on your machine:
6+
7+
```shell
8+
gcloud auth application-default login
9+
```
10+
Executing this command will save your application credentials to default path which will depend on the type of machine -
11+
- Linux, macOS: `$HOME/.config/gcloud/application_default_credentials.json`
12+
- Windows: `%APPDATA%\gcloud\application_default_credentials.json`
13+
14+
Next, set your endpoint with the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable:
15+
16+
```shell
17+
export OTEL_EXPORTER_OTLP_ENDPOINT="http://your-endpoint:port"
18+
```
19+
20+
Next, update [`build.gradle`](build.grade) to set the following:
21+
22+
```
23+
'-Dotel.resource.attributes=gcp.project_id=<YOUR_PROJECT_ID>,
24+
'-Dotel.exporter.otlp.headers=X-Goog-User-Project=<YOUR_QUOTA_PROJECT>',
25+
# Optional - if you want to export using gRPC protocol
26+
'-Dotel.exporter.otlp.protocol=grpc',
27+
```
28+
29+
Finally, to run the sample from the project root:
30+
31+
```
32+
cd examples/otlpmetric && gradle run
33+
```

examples/otlpmetric/build.gradle

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2025 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+
plugins {
17+
id 'java'
18+
id 'application'
19+
}
20+
// examples are not published, so version can be hardcoded
21+
version = '0.1.0'
22+
23+
mainClassName = 'com.google.cloud.opentelemetry.example.otlpmetric.OTLPMetricExample'
24+
25+
description = 'Example for OTLP Metric exporter'
26+
27+
dependencies {
28+
implementation(libraries.opentelemetry_api)
29+
implementation(libraries.opentelemetry_sdk)
30+
implementation(libraries.opentelemetry_otlp_exporter)
31+
implementation(libraries.opentelemetry_sdk_autoconf)
32+
implementation(libraries.google_auth)
33+
}
34+
35+
// Provide headers from env variable
36+
// export OTEL_EXPORTER_OTLP_ENDPOINT="http://path/to/yourendpoint:port"
37+
def autoconf_config = [
38+
'-Dotel.resource.attributes=gcp.project_id=<YOUR_PROJECT>',
39+
'-Dotel.exporter.otlp.headers=X-Goog-User-Project=<YOUR_QUOTA_PROJECT>',
40+
'-Dotel.metrics.exporter=otlp',
41+
'-Dotel.exporter.otlp.protocol=http/protobuf',
42+
'-Dotel.java.global-autoconfigure.enabled=true',
43+
]
44+
45+
application {
46+
applicationDefaultJvmArgs = autoconf_config
47+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright 2025 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+
package com.google.cloud.opentelemetry.example.otlpmetric;
17+
18+
import com.google.auth.oauth2.GoogleCredentials;
19+
import io.opentelemetry.api.metrics.LongCounter;
20+
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
21+
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder;
22+
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
23+
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
24+
import io.opentelemetry.sdk.OpenTelemetrySdk;
25+
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
26+
import io.opentelemetry.sdk.common.CompletableResultCode;
27+
import io.opentelemetry.sdk.metrics.export.MetricExporter;
28+
import java.io.IOException;
29+
import java.util.Random;
30+
import java.util.concurrent.TimeUnit;
31+
32+
public class OTLPMetricExample {
33+
private static final String INSTRUMENTATION_SCOPE_NAME = OTLPMetricExample.class.getName();
34+
private static final Random RANDOM = new Random();
35+
36+
private static OpenTelemetrySdk openTelemetrySdk;
37+
38+
private static OpenTelemetrySdk setupMetricExporter() throws IOException {
39+
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
40+
41+
// Update the SDK configured using environment variables and system properties
42+
// TODO: Replace this with the use of gcp-auth-extension
43+
AutoConfiguredOpenTelemetrySdk autoConfOTelSdk =
44+
AutoConfiguredOpenTelemetrySdk.builder()
45+
.addMetricExporterCustomizer(
46+
(exporter, configProperties) -> addAuthorizationHeaders(exporter, credentials))
47+
.build();
48+
return autoConfOTelSdk.getOpenTelemetrySdk();
49+
}
50+
51+
// Modifies the metric exporter initially auto-configured using environment variables
52+
// Note: This adds static authorization headers which are set only at initialization time.
53+
// This will stop working after the token expires, since the token is not refreshed.
54+
private static MetricExporter addAuthorizationHeaders(
55+
MetricExporter exporter, GoogleCredentials credentials) {
56+
if (exporter instanceof OtlpHttpMetricExporter) {
57+
try {
58+
credentials.refreshIfExpired();
59+
OtlpHttpMetricExporterBuilder builder =
60+
((OtlpHttpMetricExporter) exporter)
61+
.toBuilder()
62+
.addHeader(
63+
"Authorization", "Bearer " + credentials.getAccessToken().getTokenValue());
64+
65+
return builder.build();
66+
} catch (IOException e) {
67+
System.out.println("error:" + e.getMessage());
68+
}
69+
} else if (exporter instanceof OtlpGrpcMetricExporter) {
70+
try {
71+
credentials.refreshIfExpired();
72+
OtlpGrpcMetricExporterBuilder builder =
73+
((OtlpGrpcMetricExporter) exporter)
74+
.toBuilder()
75+
.addHeader(
76+
"Authorization", "Bearer " + credentials.getAccessToken().getTokenValue());
77+
return builder.build();
78+
} catch (IOException e) {
79+
throw new RuntimeException(e);
80+
}
81+
}
82+
return exporter;
83+
}
84+
85+
private static void myUseCase() {
86+
LongCounter counter =
87+
openTelemetrySdk
88+
.getMeter(INSTRUMENTATION_SCOPE_NAME)
89+
.counterBuilder("example_counter")
90+
.setDescription("Processed jobs")
91+
.setUnit("1")
92+
.build();
93+
doWork(counter);
94+
}
95+
96+
private static void doWork(LongCounter counter) {
97+
try {
98+
for (int i = 0; i < 10; i++) {
99+
counter.add(RANDOM.nextInt(100));
100+
Thread.sleep(RANDOM.nextInt(1000));
101+
}
102+
} catch (InterruptedException e) {
103+
throw new RuntimeException(e);
104+
}
105+
}
106+
107+
public static void main(String[] args) throws IOException {
108+
// Configure the OpenTelemetry pipeline with CloudMetric exporter
109+
openTelemetrySdk = setupMetricExporter();
110+
111+
// Application-specific logic
112+
myUseCase();
113+
myUseCase();
114+
115+
// Flush all buffered metrics
116+
CompletableResultCode completableResultCode = openTelemetrySdk.getSdkMeterProvider().shutdown();
117+
// wait till export finishes
118+
completableResultCode.join(10000, TimeUnit.MILLISECONDS);
119+
}
120+
}

settings.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ include ":exporter-trace"
2929
include ":examples-trace"
3030
include ":examples-otlp-spring"
3131
include ":examples-otlptrace"
32+
include ":examples-otlpmetric"
3233
include ":examples-otlpmetrics-function"
3334
include ":exporter-metrics"
3435
include ":examples-metrics"
@@ -107,3 +108,6 @@ project(':examples-spring').projectDir =
107108

108109
project(':examples-otlpmetrics-function').projectDir =
109110
"$rootDir/examples/otlpmetrics-function" as File
111+
112+
project(':examples-otlpmetric').projectDir =
113+
"$rootDir/examples/otlpmetric" as File

0 commit comments

Comments
 (0)