Skip to content

Commit 0f031c6

Browse files
damemipsx95
andauthored
Add OTLP trace with ADC example (#297)
* Add OTLP trace with ADC example * Add gradle build * fix autoconfiguration for otlp exporter * Programmatically configure auth headers * Refresh credentials and add readme * Spotless apply * Update README.md * Feedback --------- Co-authored-by: Pranav Sharma <[email protected]>
1 parent 4c1737f commit 0f031c6

File tree

5 files changed

+198
-0
lines changed

5 files changed

+198
-0
lines changed

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ subprojects {
138138
autoServiceVersion = '1.1.1'
139139
autoValueVersion = '1.10.4'
140140
slf4jVersion = '2.0.9'
141+
googleAuthVersion = '1.23.0'
141142
googleCloudVersion = '2.27.0'
142143
googleTraceVersion = '2.30.0'
143144
googleCloudBom = '26.26.0'
@@ -169,6 +170,7 @@ subprojects {
169170
auto_value_annotations : "com.google.auto.value:auto-value-annotations:${autoValueVersion}",
170171
auto_value : "com.google.auto.value:auto-value:${autoValueVersion}",
171172
cloudevents_core : "io.cloudevents:cloudevents-core:${cloudEventsCoreVersion}",
173+
google_auth : "com.google.auth:google-auth-library-oauth2-http:${googleAuthVersion}",
172174
google_cloud_core : "com.google.cloud:google-cloud-core:${googleCloudVersion}",
173175
google_cloud_trace : "com.google.cloud:google-cloud-trace:${googleTraceVersion}",
174176
google_cloud_trace_grpc : "com.google.api.grpc:grpc-google-cloud-trace-v2:${googleTraceVersion}",

examples/otlptrace/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# OTLP Trace 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+
```
26+
27+
Finally, to run the sample from the project root:
28+
29+
```
30+
cd examples/otlptrace && gradle run
31+
```

examples/otlptrace/build.gradle

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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+
plugins {
17+
id 'java'
18+
id 'application'
19+
}
20+
21+
mainClassName = 'com.google.cloud.opentelemetry.example.otlptrace.OTLPTraceExample'
22+
23+
description = 'Example for OTLP exporter'
24+
25+
dependencies {
26+
implementation(libraries.opentelemetry_api)
27+
implementation(libraries.opentelemetry_sdk)
28+
implementation(libraries.opentelemetry_otlp_exporter)
29+
implementation(libraries.opentelemetry_sdk_autoconf)
30+
implementation(libraries.google_auth)
31+
}
32+
33+
// Provide headers from env variable
34+
// export OTEL_EXPORTER_OTLP_ENDPOINT="http://path/to/yourendpoint:port"
35+
def autoconf_config = [
36+
'-Dotel.resource.attributes=gcp.project_id=<YOUR_PROJECT>',
37+
'-Dotel.exporter.otlp.headers=X-Goog-User-Project=<YOUR_QUOTA_PROJECT>',
38+
'-Dotel.traces.exporter=otlp',
39+
'-Dotel.exporter.otlp.protocol=http/protobuf',
40+
'-Dotel.java.global-autoconfigure.enabled=true',
41+
]
42+
43+
application {
44+
applicationDefaultJvmArgs = autoconf_config
45+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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+
package com.google.cloud.opentelemetry.example.otlptrace;
17+
18+
import com.google.auth.oauth2.GoogleCredentials;
19+
import io.opentelemetry.api.trace.Span;
20+
import io.opentelemetry.context.Scope;
21+
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
22+
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
23+
import io.opentelemetry.sdk.OpenTelemetrySdk;
24+
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
25+
import io.opentelemetry.sdk.common.CompletableResultCode;
26+
import io.opentelemetry.sdk.trace.export.SpanExporter;
27+
import java.io.*;
28+
import java.io.IOException;
29+
import java.util.Random;
30+
import java.util.concurrent.TimeUnit;
31+
32+
public class OTLPTraceExample {
33+
private static final String INSTRUMENTATION_SCOPE_NAME = OTLPTraceExample.class.getName();
34+
private static final Random random = new Random();
35+
36+
private static OpenTelemetrySdk openTelemetrySdk;
37+
38+
private static OpenTelemetrySdk setupTraceExporter() throws IOException {
39+
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
40+
41+
// Update the SDK configured using environment variables and system properties
42+
AutoConfiguredOpenTelemetrySdk autoConfOTelSdk =
43+
AutoConfiguredOpenTelemetrySdk.builder()
44+
.addSpanExporterCustomizer(
45+
(exporter, configProperties) -> addAuthorizationHeaders(exporter, credentials))
46+
.build();
47+
return autoConfOTelSdk.getOpenTelemetrySdk();
48+
}
49+
50+
// Modifies the span exporter initially auto-configured using environment variables
51+
private static SpanExporter addAuthorizationHeaders(
52+
SpanExporter exporter, GoogleCredentials credentials) {
53+
if (exporter instanceof OtlpHttpSpanExporter) {
54+
try {
55+
credentials.refreshIfExpired();
56+
OtlpHttpSpanExporterBuilder builder =
57+
((OtlpHttpSpanExporter) exporter)
58+
.toBuilder()
59+
.addHeader(
60+
"Authorization", "Bearer " + credentials.getAccessToken().getTokenValue());
61+
62+
return builder.build();
63+
} catch (IOException e) {
64+
System.out.println("error:" + e.getMessage());
65+
}
66+
}
67+
return exporter;
68+
}
69+
70+
private static void myUseCase(String description) {
71+
// Generate a span
72+
Span span =
73+
openTelemetrySdk.getTracer(INSTRUMENTATION_SCOPE_NAME).spanBuilder(description).startSpan();
74+
try (Scope scope = span.makeCurrent()) {
75+
span.addEvent("Event A");
76+
// Do some work for the use case
77+
for (int i = 0; i < 3; i++) {
78+
String work = String.format("%s - Work #%d", description, (i + 1));
79+
doWork(work);
80+
}
81+
82+
span.addEvent("Event B");
83+
} finally {
84+
span.end();
85+
}
86+
}
87+
88+
private static void doWork(String description) {
89+
// Child span
90+
Span span =
91+
openTelemetrySdk.getTracer(INSTRUMENTATION_SCOPE_NAME).spanBuilder(description).startSpan();
92+
try (Scope scope = span.makeCurrent()) {
93+
// Simulate work: this could be simulating a network request or an expensive disk operation
94+
Thread.sleep(100 + random.nextInt(5) * 100);
95+
} catch (InterruptedException e) {
96+
throw new RuntimeException(e);
97+
} finally {
98+
span.end();
99+
}
100+
}
101+
102+
public static void main(String[] args) throws IOException {
103+
// Configure the OpenTelemetry pipeline with CloudTrace exporter
104+
openTelemetrySdk = setupTraceExporter();
105+
106+
// Application-specific logic
107+
myUseCase("One");
108+
myUseCase("Two");
109+
110+
// Flush all buffered traces
111+
CompletableResultCode completableResultCode =
112+
openTelemetrySdk.getSdkTracerProvider().shutdown();
113+
// wait till export finishes
114+
completableResultCode.join(10000, TimeUnit.MILLISECONDS);
115+
}
116+
}

settings.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ rootProject.name = "opentelemetry-operations-java"
2626

2727
include ":exporter-trace"
2828
include ":examples-trace"
29+
include ":examples-otlptrace"
2930
include ":exporter-metrics"
3031
include ":examples-metrics"
3132
include ":exporter-auto"
@@ -45,6 +46,9 @@ project(':exporter-trace').projectDir =
4546
project(':examples-trace').projectDir =
4647
"$rootDir/examples/trace" as File
4748

49+
project(':examples-otlptrace').projectDir =
50+
"$rootDir/examples/otlptrace" as File
51+
4852
project(':exporter-metrics').projectDir =
4953
"$rootDir/exporters/metrics" as File
5054

0 commit comments

Comments
 (0)