Skip to content

Commit addbc31

Browse files
Kavindu-Dodanthisthattoddbaert
authored
feat: Allow global otel configuration extraction (#505)
Signed-off-by: Kavindu Dodanduwa <[email protected]> Co-authored-by: Giovanni Liva <[email protected]> Co-authored-by: Todd Baert <[email protected]>
1 parent f397c56 commit addbc31

File tree

5 files changed

+91
-11
lines changed

5 files changed

+91
-11
lines changed

providers/flagd/README.md

+27-8
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,21 @@ By default, the provider is configured to
146146
use [least recently used (lru)](https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/LRUMap.html)
147147
caching with up to 1000 entries.
148148

149-
### OpenTelemetry support (RPC only)
149+
### OpenTelemetry tracing (RPC only)
150150

151-
OpenTelemetry support can be enabled either through [automatic instrumentation](https://opentelemetry.io/docs/instrumentation/java/automatic/)
152-
or with [manual instrumentation](https://opentelemetry.io/docs/instrumentation/java/manual/).
151+
flagd provider support OpenTelemetry traces for gRPC backed remote evaluations.
153152

154-
For manual instrumentation, flagd provider can be constructed with an `OpenTelemetry` instance.
153+
There are two ways you can configure OpenTelemetry for the provider,
154+
155+
- [Using automatic instrumentation](https://opentelemetry.io/docs/instrumentation/java/automatic/)
156+
- [Using manual instrumentation](https://opentelemetry.io/docs/instrumentation/java/manual/)
157+
158+
When using automatic instrumentation, traces for gRPC will be automatically added by the OpenTelemetry Java library.
159+
These traces however will not include extra attributes added when using manual instrumentation.
160+
161+
When using manual instrumentation, you have two options to construct flagd provider to enable traces.
162+
163+
First(preferred) option is by constructing the provider with an OpenTelemetry instance,
155164

156165
```java
157166
FlagdOptions options =
@@ -162,8 +171,18 @@ FlagdOptions options =
162171
FlagdProvider flagdProvider = new FlagdProvider(options);
163172
```
164173

165-
Please refer [OpenTelemetry example](https://opentelemetry.io/docs/instrumentation/java/manual/#example) for best
166-
practice guideline.
174+
Second option is useful if you have set up a GlobalOpenTelemetry in your runtime.
175+
You can allow flagd to derive the OpenTelemetry instance by enabling `withGlobalTelemetry` option.
176+
177+
```java
178+
FlagdOptions options =
179+
FlagdOptions.builder()
180+
.withGlobalTelemetry(true)
181+
.build();
182+
183+
FlagdProvider flagdProvider = new FlagdProvider(options);
184+
```
185+
186+
Please refer [OpenTelemetry example](https://opentelemetry.io/docs/instrumentation/java/manual/#example) for best practice guideline.
167187

168-
Telemetry configuration combined with [flagd telemetry ](https://github.com/open-feature/flagd/blob/main/docs/configuration/flagd_telemetry.md)
169-
allows distributed tracing.
188+
Provider telemetry combined with [flagd OpenTelemetry](https://flagd.dev/reference/monitoring/#opentelemetry) allows you to have distributed traces.

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/FlagdOptions.java

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.openfeature.contrib.providers.flagd;
22

3+
import io.opentelemetry.api.GlobalOpenTelemetry;
34
import io.opentelemetry.api.OpenTelemetry;
45
import lombok.Builder;
56
import lombok.Getter;
@@ -151,5 +152,15 @@ public FlagdOptionsBuilder offlineFlagSourcePath(@Nonnull final String offlineFl
151152
private FlagdOptionsBuilder isOffline(final boolean isOffline) {
152153
return this;
153154
}
155+
156+
/**
157+
* Enable OpenTelemetry instance extraction from GlobalOpenTelemetry. Note that, this is only useful if global
158+
* configurations are registered.
159+
*/
160+
public FlagdOptionsBuilder withGlobalTelemetry(final boolean b) {
161+
this.openTelemetry = GlobalOpenTelemetry.get();
162+
163+
return this;
164+
}
154165
}
155166
}

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/grpc/strategy/ResolveFactory.java

+2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
public final class ResolveFactory {
99
/**
1010
* Factory method to initialize the resolving strategy.
11+
*
1112
* @param options Options.
1213
* @return the ResolveStrategy based on the provided options.
1314
*/
1415
public static ResolveStrategy getStrategy(FlagdOptions options) {
1516
if (options.getOpenTelemetry() != null) {
1617
return new TracedResolving(options.getOpenTelemetry());
1718
}
19+
1820
return new SimpleResolving();
1921
}
2022
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package dev.openfeature.contrib.providers.flagd.resolver.grpc.strategy;
2+
3+
import dev.openfeature.contrib.providers.flagd.FlagdOptions;
4+
import io.opentelemetry.api.OpenTelemetry;
5+
import org.junit.jupiter.api.Test;
6+
import org.mockito.Mockito;
7+
8+
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
10+
class ResolveFactoryTest {
11+
12+
@Test
13+
public void simpleResolverAsDefault() {
14+
// given
15+
final FlagdOptions options = FlagdOptions.builder().build();
16+
17+
// when
18+
final ResolveStrategy strategy = ResolveFactory.getStrategy(options);
19+
20+
// then
21+
assertEquals(SimpleResolving.class, strategy.getClass());
22+
}
23+
24+
25+
@Test
26+
public void tracedResolverWhenOTelSdkIsSet() {
27+
// given
28+
final OpenTelemetry telemetry = Mockito.mock(OpenTelemetry.class);
29+
30+
final FlagdOptions options = FlagdOptions.builder().openTelemetry(telemetry).build();
31+
32+
// when
33+
final ResolveStrategy strategy = ResolveFactory.getStrategy(options);
34+
35+
// then
36+
assertEquals(TracedResolving.class, strategy.getClass());
37+
}
38+
39+
@Test
40+
public void tracedResolverWhenGlobalTelemetryIsSet() {
41+
// given
42+
final FlagdOptions options = FlagdOptions.builder().withGlobalTelemetry(true).build();
43+
44+
// when
45+
final ResolveStrategy strategy = ResolveFactory.getStrategy(options);
46+
47+
// then
48+
assertEquals(TracedResolving.class, strategy.getClass());
49+
}
50+
}

providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/grpc/strategy/TracedResolvingTest.java

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package dev.openfeature.contrib.providers.flagd.resolver.grpc.strategy;
22

3-
43
import com.google.protobuf.Message;
5-
import dev.openfeature.contrib.providers.flagd.resolver.grpc.strategy.TracedResolving;
64
import dev.openfeature.flagd.grpc.Schema;
75
import io.opentelemetry.api.OpenTelemetry;
86
import io.opentelemetry.api.trace.Span;
@@ -20,7 +18,7 @@
2018
class TracedResolvingTest {
2119

2220
@Test
23-
public void basicTest(){
21+
public void basicTest() {
2422
// given
2523
final String key = "flagA";
2624
final OpenTelemetry openTelemetry = mock(OpenTelemetry.class);

0 commit comments

Comments
 (0)