Skip to content

Commit 8163bb4

Browse files
committed
feat: Add FirestoreOpenTelemetryOptions to FirestoreOptions.
1 parent c2812f7 commit 8163bb4

File tree

4 files changed

+236
-1
lines changed

4 files changed

+236
-1
lines changed

google-cloud-firestore/pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,13 @@
112112
<groupId>com.google.protobuf</groupId>
113113
<artifactId>protobuf-java-util</artifactId>
114114
</dependency>
115-
115+
<!-- OpenTelemetry -->
116+
<dependency>
117+
<groupId>io.opentelemetry</groupId>
118+
<artifactId>opentelemetry-api</artifactId>
119+
<version>1.29.0</version>
120+
</dependency>
121+
<!-- END OpenTelemetry -->
116122

117123
<!-- Test dependencies -->
118124
<dependency>
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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+
17+
package com.google.cloud.firestore;
18+
19+
import io.opentelemetry.api.OpenTelemetry;
20+
import javax.annotation.Nonnull;
21+
import javax.annotation.Nullable;
22+
23+
public class FirestoreOpenTelemetryOptions {
24+
private final boolean enabled;
25+
26+
@Nullable private final OpenTelemetry openTelemetry;
27+
28+
FirestoreOpenTelemetryOptions(Builder builder) {
29+
this.enabled = builder.enabled;
30+
this.openTelemetry = builder.openTelemetry;
31+
}
32+
33+
public boolean getEnabled() {
34+
return enabled;
35+
}
36+
37+
public OpenTelemetry getOpenTelemetry() {
38+
return openTelemetry;
39+
}
40+
41+
@Nonnull
42+
public FirestoreOpenTelemetryOptions.Builder toBuilder() {
43+
return new FirestoreOpenTelemetryOptions.Builder(this);
44+
}
45+
46+
@Nonnull
47+
public static FirestoreOpenTelemetryOptions.Builder newBuilder() {
48+
return new FirestoreOpenTelemetryOptions.Builder();
49+
}
50+
51+
public static class Builder {
52+
53+
private boolean enabled;
54+
55+
@Nullable private OpenTelemetry openTelemetry;
56+
57+
private Builder() {
58+
enabled = false;
59+
openTelemetry = null;
60+
}
61+
62+
private Builder(FirestoreOpenTelemetryOptions options) {
63+
this.enabled = options.enabled;
64+
this.openTelemetry = options.openTelemetry;
65+
}
66+
67+
@Nonnull
68+
public FirestoreOpenTelemetryOptions build() {
69+
return new FirestoreOpenTelemetryOptions(this);
70+
}
71+
72+
/**
73+
* Sets whether tracing should be enabled.
74+
*
75+
* @param enable Whether tracing should be enabled.
76+
*/
77+
@Nonnull
78+
public FirestoreOpenTelemetryOptions.Builder setTracingEnabled(boolean enable) {
79+
this.enabled = enable;
80+
return this;
81+
}
82+
83+
/**
84+
* Sets the {@link OpenTelemetry} to use with this Firestore instance. If telemetry collection
85+
* is enabled, but an `OpenTelemetry` is not provided, the Firestore SDK will attempt to use the
86+
* `GlobalOpenTelemetry`.
87+
*
88+
* @param openTelemetry The OpenTelemetry that should be used by this Firestore instance.
89+
*/
90+
@Nonnull
91+
public FirestoreOpenTelemetryOptions.Builder setOpenTelemetry(
92+
@Nonnull OpenTelemetry openTelemetry) {
93+
this.openTelemetry = openTelemetry;
94+
return this;
95+
}
96+
}
97+
}

google-cloud-firestore/src/main/java/com/google/cloud/firestore/FirestoreOptions.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.google.cloud.firestore;
1818

19+
import com.google.api.core.BetaApi;
1920
import com.google.api.core.InternalApi;
2021
import com.google.api.gax.core.CredentialsProvider;
2122
import com.google.api.gax.core.FixedCredentialsProvider;
@@ -60,6 +61,7 @@ public final class FirestoreOptions extends ServiceOptions<Firestore, FirestoreO
6061
private final TransportChannelProvider channelProvider;
6162
private final CredentialsProvider credentialsProvider;
6263
private final String emulatorHost;
64+
@Nonnull private final FirestoreOpenTelemetryOptions openTelemetryOptions;
6365

6466
public static class DefaultFirestoreFactory implements FirestoreFactory {
6567

@@ -118,12 +120,19 @@ public String getEmulatorHost() {
118120
return emulatorHost;
119121
}
120122

123+
@BetaApi
124+
@Nonnull
125+
public FirestoreOpenTelemetryOptions getOpenTelemetryOptions() {
126+
return openTelemetryOptions;
127+
}
128+
121129
public static class Builder extends ServiceOptions.Builder<Firestore, FirestoreOptions, Builder> {
122130

123131
@Nullable private String databaseId = null;
124132
@Nullable private TransportChannelProvider channelProvider = null;
125133
@Nullable private CredentialsProvider credentialsProvider = null;
126134
@Nullable private String emulatorHost = null;
135+
@Nullable private FirestoreOpenTelemetryOptions openTelemetryOptions = null;
127136

128137
private Builder() {}
129138

@@ -133,6 +142,7 @@ private Builder(FirestoreOptions options) {
133142
this.channelProvider = options.channelProvider;
134143
this.credentialsProvider = options.credentialsProvider;
135144
this.emulatorHost = options.emulatorHost;
145+
this.openTelemetryOptions = options.openTelemetryOptions;
136146
}
137147

138148
/**
@@ -201,6 +211,19 @@ public Builder setDatabaseId(@Nonnull String databaseId) {
201211
return this;
202212
}
203213

214+
/**
215+
* Sets the {@link FirestoreOpenTelemetryOptions} to be used for this Firestore instance.
216+
*
217+
* @param openTelemetryOptions The `FirestoreOpenTelemetryOptions` to use.
218+
*/
219+
@BetaApi
220+
@Nonnull
221+
public Builder setOpenTelemetryOptions(
222+
@Nonnull FirestoreOpenTelemetryOptions openTelemetryOptions) {
223+
this.openTelemetryOptions = openTelemetryOptions;
224+
return this;
225+
}
226+
204227
@Override
205228
@Nonnull
206229
public FirestoreOptions build() {
@@ -212,6 +235,10 @@ public FirestoreOptions build() {
212235
}
213236
}
214237

238+
if (this.openTelemetryOptions == null) {
239+
this.setOpenTelemetryOptions(FirestoreOpenTelemetryOptions.newBuilder().build());
240+
}
241+
215242
// Override credentials and channel provider if we are using the emulator.
216243
if (emulatorHost == null) {
217244
emulatorHost = System.getenv(FIRESTORE_EMULATOR_SYSTEM_VARIABLE);
@@ -278,6 +305,12 @@ public void refresh() {}
278305
protected FirestoreOptions(Builder builder) {
279306
super(FirestoreFactory.class, FirestoreRpcFactory.class, builder, new FirestoreDefaults());
280307

308+
if (builder.openTelemetryOptions == null) {
309+
this.openTelemetryOptions = FirestoreOpenTelemetryOptions.newBuilder().build();
310+
} else {
311+
this.openTelemetryOptions = builder.openTelemetryOptions;
312+
}
313+
281314
this.databaseId =
282315
builder.databaseId != null
283316
? builder.databaseId
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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+
17+
package com.google.cloud.firestore;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import io.opentelemetry.api.GlobalOpenTelemetry;
22+
import io.opentelemetry.api.OpenTelemetry;
23+
import javax.annotation.Nullable;
24+
import org.junit.*;
25+
26+
public class OpenTelemetryOptionsTest {
27+
@Nullable private Firestore firestore;
28+
29+
@Before
30+
public void setUp() {
31+
GlobalOpenTelemetry.resetForTest();
32+
}
33+
34+
@After
35+
public void tearDown() {
36+
if (firestore != null) {
37+
firestore.shutdown();
38+
firestore = null;
39+
}
40+
}
41+
42+
FirestoreOptions.Builder getBaseOptions() {
43+
return FirestoreOptions.newBuilder().setProjectId("test-project").setDatabaseId("(default)");
44+
}
45+
46+
@Test
47+
public void defaultOptionsDisablesTelemetryCollection() {
48+
FirestoreOptions firestoreOptions = getBaseOptions().build();
49+
firestore = firestoreOptions.getService();
50+
assertThat(firestore.getOptions().getOpenTelemetryOptions().getEnabled()).isFalse();
51+
assertThat(firestore.getOptions().getOpenTelemetryOptions().getOpenTelemetry()).isNull();
52+
}
53+
54+
@Test
55+
public void canEnableTelemetryCollectionWithoutOpenTelemetryInstance() {
56+
FirestoreOptions firestoreOptions =
57+
getBaseOptions()
58+
.setOpenTelemetryOptions(
59+
FirestoreOpenTelemetryOptions.newBuilder().setTracingEnabled(true).build())
60+
.build();
61+
firestore = firestoreOptions.getService();
62+
assertThat(firestore.getOptions().getOpenTelemetryOptions().getEnabled()).isTrue();
63+
assertThat(firestore.getOptions().getOpenTelemetryOptions().getOpenTelemetry()).isNull();
64+
}
65+
66+
@Test
67+
public void canEnableTelemetryCollectionWithOpenTelemetryInstance() {
68+
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
69+
FirestoreOptions firestoreOptions =
70+
getBaseOptions()
71+
.setOpenTelemetryOptions(
72+
FirestoreOpenTelemetryOptions.newBuilder()
73+
.setTracingEnabled(true)
74+
.setOpenTelemetry(openTelemetry)
75+
.build())
76+
.build();
77+
firestore = firestoreOptions.getService();
78+
assertThat(firestore.getOptions().getOpenTelemetryOptions().getEnabled()).isTrue();
79+
assertThat(firestore.getOptions().getOpenTelemetryOptions().getOpenTelemetry())
80+
.isEqualTo(openTelemetry);
81+
}
82+
83+
@Test
84+
public void canDisableTelemetryCollectionWhileOpenTelemetryInstanceIsNotNull() {
85+
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
86+
FirestoreOptions firestoreOptions =
87+
getBaseOptions()
88+
.setOpenTelemetryOptions(
89+
FirestoreOpenTelemetryOptions.newBuilder()
90+
.setTracingEnabled(false)
91+
.setOpenTelemetry(openTelemetry)
92+
.build())
93+
.build();
94+
firestore = firestoreOptions.getService();
95+
assertThat(firestore.getOptions().getOpenTelemetryOptions().getEnabled()).isFalse();
96+
assertThat(firestore.getOptions().getOpenTelemetryOptions().getOpenTelemetry())
97+
.isEqualTo(openTelemetry);
98+
}
99+
}

0 commit comments

Comments
 (0)