Skip to content

Commit 2533953

Browse files
authored
switch to micronaut tracing (#201)
* switch to micronaut tracing switch back to micronaut's built-in tracing functionality
1 parent f332493 commit 2533953

File tree

17 files changed

+98
-261
lines changed

17 files changed

+98
-261
lines changed

pom.xml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,6 @@
141141
<groupId>io.opentelemetry</groupId>
142142
<artifactId>opentelemetry-exporter-otlp</artifactId>
143143
</dependency>
144-
<dependency>
145-
<groupId>io.opentelemetry.instrumentation</groupId>
146-
<artifactId>opentelemetry-instrumentation-annotations</artifactId>
147-
</dependency>
148144
<dependency>
149145
<groupId>io.micronaut.cache</groupId>
150146
<artifactId>micronaut-cache-core</artifactId>
@@ -439,11 +435,6 @@
439435
<artifactId>micronaut-openapi</artifactId>
440436
<version>${micronaut.openapi.version}</version>
441437
</path>
442-
<path>
443-
<groupId>io.micronaut.tracing</groupId>
444-
<artifactId>micronaut-tracing-opentelemetry-annotation</artifactId>
445-
<version>${micronaut.tracing.version}</version>
446-
</path>
447438
<path>
448439
<groupId>com.google.auto.service</groupId>
449440
<artifactId>auto-service</artifactId>

src/main/java/no/ssb/dlp/pseudo/service/accessgroups/CloudIdentityService.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package no.ssb.dlp.pseudo.service.accessgroups;
22

33
import io.micronaut.cache.annotation.Cacheable;
4+
import io.micronaut.tracing.annotation.NewSpan;
5+
import io.micronaut.tracing.annotation.SpanTag;
6+
import io.opentelemetry.api.trace.Tracer;
47
import io.reactivex.Flowable;
8+
import org.reactivestreams.Publisher;
59
import jakarta.inject.Singleton;
610
import lombok.RequiredArgsConstructor;
7-
import no.ssb.dlp.pseudo.service.tracing.SpanAttribute;
8-
import no.ssb.dlp.pseudo.service.tracing.WithSpan;
911

1012
import java.util.ArrayList;
1113
import java.util.List;
@@ -14,10 +16,11 @@
1416
@RequiredArgsConstructor
1517
public class CloudIdentityService {
1618
private final CloudIdentityClient cloudIdentityClient;
19+
private final Tracer tracer;
1720

18-
@WithSpan
21+
@NewSpan
1922
@Cacheable(value = "cloud-identity-service-cache", parameters = {"groupEmail"})
20-
public List<Membership> listMembers(@SpanAttribute String groupEmail) {
23+
public List<Membership> listMembers(@SpanTag String groupEmail) {
2124
return Flowable.fromPublisher(cloudIdentityClient.lookup(groupEmail))
2225
.flatMap(lookupResponse -> fetchMemberships(lookupResponse.getGroupName(), null,
2326
new ArrayList<>()))
@@ -32,19 +35,22 @@ public List<Membership> listMembers(@SpanAttribute String groupEmail) {
3235
* @param allMemberships a list that will be populated with all memberships
3336
* @return the list of all memberships
3437
*/
35-
@WithSpan
36-
protected Flowable<List<Membership>> fetchMemberships(
37-
@SpanAttribute String groupId,
38-
@SpanAttribute String nextPageToken,
38+
private Publisher<List<Membership>> fetchMemberships(
39+
String groupId,
40+
String nextPageToken,
3941
List<Membership> allMemberships
4042
) {
43+
final var span = tracer.spanBuilder("fetchMemberships").startSpan();
44+
span.setAttribute("groupId", groupId);
45+
span.setAttribute("nextPageToken", nextPageToken);
4146
if (groupId == null || groupId.isEmpty()) {
4247
return Flowable.just(allMemberships);
4348
}
4449
return Flowable.fromPublisher(cloudIdentityClient.listMembers(groupId, nextPageToken))
4550
.flatMap(membershipResponse -> {
4651
allMemberships.addAll(membershipResponse.getMemberships());
4752
String nextToken = membershipResponse.getNextPageToken();
53+
span.end();
4854
return nextToken != null ?
4955
fetchMemberships(groupId, nextToken, allMemberships) :
5056
Flowable.just(allMemberships);

src/main/java/no/ssb/dlp/pseudo/service/filters/AccessTokenFilter.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010
import io.micronaut.http.filter.ClientFilterChain;
1111
import io.micronaut.http.filter.HttpClientFilter;
1212
import io.micronaut.inject.qualifiers.Qualifiers;
13+
import io.micronaut.tracing.annotation.NewSpan;
14+
import io.opentelemetry.api.trace.Span;
15+
import io.opentelemetry.api.trace.Tracer;
1316
import jakarta.annotation.Nullable;
1417
import lombok.Data;
1518
import lombok.SneakyThrows;
1619
import lombok.extern.slf4j.Slf4j;
1720
import org.reactivestreams.Publisher;
18-
import no.ssb.dlp.pseudo.service.tracing.WithSpan;
19-
import no.ssb.dlp.pseudo.service.tracing.WithSpanContext;
2021

2122
import jakarta.inject.Inject;
2223
import jakarta.inject.Singleton;
@@ -43,9 +44,10 @@ public class AccessTokenFilter implements HttpClientFilter {
4344
@Value("${gcp.http.client.filter.project-id}")
4445
private String projectId;
4546
private final GoogleCredentials credentials;
47+
private final Tracer tracer;
4648

4749
@SneakyThrows
48-
public AccessTokenFilter(@Nullable @Value("${gcp.http.client.filter.credentials-path}") String credentialsPath) {
50+
public AccessTokenFilter(@Nullable @Value("${gcp.http.client.filter.credentials-path}") String credentialsPath, Tracer tracer) {
4951
if (credentialsPath == null) {
5052
log.info("Using Application Default Credentials");
5153
this.credentials = GoogleCredentials.getApplicationDefault();
@@ -54,12 +56,13 @@ public AccessTokenFilter(@Nullable @Value("${gcp.http.client.filter.credentials-
5456
this.credentials = GoogleCredentials.fromStream(
5557
new FileInputStream(credentialsPath));
5658
}
59+
this.tracer = tracer;
5760
}
5861

5962
@SneakyThrows
60-
@WithSpan
63+
@NewSpan
6164
public Publisher<? extends HttpResponse<?>> doFilter(MutableHttpRequest<?> request, ClientFilterChain chain) {
62-
final var currentSpan = WithSpanContext.currentSpan();
65+
final var currentSpan = Span.current();
6366
currentSpan.setAttribute("request.url", request.getUri().toString());
6467
final var config = request.getAttribute("micronaut.http.serviceId").map(Object::toString).flatMap(this::getConfig);
6568
currentSpan.addEvent("Add bearer auth", Instant.now());
@@ -83,18 +86,20 @@ private void setProjectIdHeader(MutableHttpRequest<?> request) {
8386
}
8487

8588
@SneakyThrows
86-
@WithSpan
87-
protected String getAccessToken(String audience) {
88-
return credentials.createScoped(audience).refreshAccessToken().getTokenValue();
89+
private String getAccessToken(String audience) {
90+
Span span = tracer.spanBuilder("getAccessToken").startSpan();
91+
final var result = credentials.createScoped(audience).refreshAccessToken().getTokenValue();
92+
span.end();
93+
return result;
8994
}
9095

91-
@Cacheable(value="access-token-filter-cache", parameters = {"serviceId"})
92-
@WithSpan
96+
@Cacheable(value = "access-token-filter-cache", parameters = {"serviceId"})
97+
@NewSpan
9398
protected Optional<AccessTokenFilterConfig> getConfig(String serviceId) {
9499
return Optional
95100
.ofNullable(applicationContext)
96101
.flatMap(ac ->
97-
ac.findBean(AccessTokenFilterConfig.class, Qualifiers.byName(serviceId))
102+
ac.findBean(AccessTokenFilterConfig.class, Qualifiers.byName(serviceId))
98103
);
99104
}
100105

src/main/java/no/ssb/dlp/pseudo/service/pseudo/PseudoController.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import io.micronaut.scheduling.TaskExecutors;
1010
import io.micronaut.scheduling.annotation.ExecuteOn;
1111
import io.micronaut.security.annotation.Secured;
12+
import io.micronaut.tracing.annotation.NewSpan;
13+
import io.opentelemetry.api.trace.Tracer;
1214
import io.reactivex.Flowable;
1315
import io.opentelemetry.api.trace.Span;
1416
import io.swagger.v3.oas.annotations.Operation;
@@ -26,8 +28,6 @@
2628
import no.ssb.dlp.pseudo.service.sid.InvalidSidSnapshotDateException;
2729
import no.ssb.dlp.pseudo.service.sid.SidIndexUnavailableException;
2830

29-
import no.ssb.dlp.pseudo.service.tracing.WithSpan;
30-
import no.ssb.dlp.pseudo.service.tracing.WithSpanContext;
3131
import org.slf4j.MDC;
3232

3333
import java.lang.reflect.InvocationTargetException;
@@ -52,6 +52,7 @@ public class PseudoController {
5252
private final StreamProcessorFactory streamProcessorFactory;
5353
private final RecordMapProcessorFactory recordProcessorFactory;
5454
private final PseudoConfigSplitter pseudoConfigSplitter;
55+
private final Tracer tracer;
5556

5657
/**
5758
* Pseudonymizes a field.
@@ -60,14 +61,14 @@ public class PseudoController {
6061
* @return HTTP response containing a {@link HttpResponse<Flowable>} object.
6162
*/
6263

63-
@WithSpan
64+
@NewSpan
6465
@Operation(summary = "Pseudonymize field", description = "Pseudonymize a field.")
6566
@Produces(MediaType.APPLICATION_JSON)
6667
@Post(value = "/pseudonymize/field", consumes = MediaType.APPLICATION_JSON)
6768
@ExecuteOn(TaskExecutors.BLOCKING)
6869
public HttpResponse<Flowable<byte[]>> pseudonymizeField(@Schema(implementation = PseudoFieldRequest.class) String request) {
6970
PseudoFieldRequest req = Json.toObject(PseudoFieldRequest.class, request);
70-
final var currentSpan = WithSpanContext.currentSpan();
71+
final var currentSpan = Span.current();
7172
if (req != null) {
7273
currentSpan.setAttribute("pseudoRequest.field", req.getName());
7374
currentSpan.setAttribute("pseudoRequest.pattern", req.getPattern());
@@ -76,7 +77,6 @@ public HttpResponse<Flowable<byte[]>> pseudonymizeField(@Schema(implementation =
7677
if (values != null) {
7778
currentSpan.setAttribute("pseudoRequest.values.count", values.size());
7879
currentSpan.setAttribute("pseudoRequest.values", values.toString());
79-
Span.current().setAttribute("pseudoRequest.values", values.toString());
8080
}
8181
}
8282
log.info(Strings.padEnd(String.format("*** Pseudonymize field: %s ", req.getName()), 80, '*'));
@@ -108,7 +108,7 @@ public HttpResponse<Flowable<byte[]>> pseudonymizeField(@Schema(implementation =
108108
* @param request JSON string representing a {@link DepseudoFieldRequest} object.
109109
* @return HTTP response containing a {@link HttpResponse<Flowable>} object.
110110
*/
111-
@WithSpan
111+
@NewSpan
112112
@Operation(summary = "Depseudonymize field", description = "Depseudonymize a field.")
113113
@Produces(MediaType.APPLICATION_JSON)
114114
@Secured({PseudoServiceRole.ADMIN})
@@ -117,7 +117,7 @@ public HttpResponse<Flowable<byte[]>> pseudonymizeField(@Schema(implementation =
117117
public HttpResponse<Flowable<byte[]>> depseudonymizeField(@Schema(implementation = DepseudoFieldRequest.class) String request) {
118118
DepseudoFieldRequest req = Json.toObject(DepseudoFieldRequest.class, request);
119119
Span currentSpan = Span.current();
120-
if (currentSpan.getSpanContext().isValid() && req != null) {
120+
if (req != null) {
121121
currentSpan.setAttribute("pseudo.field", req.getName());
122122
currentSpan.setAttribute("pseudo.pattern", req.getPattern());
123123
currentSpan.setAttribute("pseudo.values.count", req.getValues() == null ? 0 : req.getValues().size());
@@ -140,7 +140,7 @@ public HttpResponse<Flowable<byte[]>> depseudonymizeField(@Schema(implementation
140140
* @param request JSON string representing a {@link RepseudoFieldRequest} object.
141141
* @return HTTP response containing a {@link HttpResponse<Flowable>} object.
142142
*/
143-
@WithSpan
143+
@NewSpan
144144
@Operation(summary = "Repseudonymize field", description = "Repseudonymize a field.")
145145
@Produces(MediaType.APPLICATION_JSON)
146146
@Secured({PseudoServiceRole.ADMIN})
@@ -149,7 +149,7 @@ public HttpResponse<Flowable<byte[]>> depseudonymizeField(@Schema(implementation
149149
public HttpResponse<Flowable<byte[]>> repseudonymizeField(@Schema(implementation = RepseudoFieldRequest.class) String request) {
150150
RepseudoFieldRequest req = Json.toObject(RepseudoFieldRequest.class, request);
151151
Span currentSpan = Span.current();
152-
if (currentSpan.getSpanContext().isValid() && req != null) {
152+
if (req != null) {
153153
currentSpan.setAttribute("pseudo.field", req.getName());
154154
currentSpan.setAttribute("pseudo.pattern", req.getPattern());
155155
currentSpan.setAttribute("pseudo.values.count", req.getValues() == null ? 0 : req.getValues().size());

src/main/java/no/ssb/dlp/pseudo/service/pseudo/PseudoField.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
package no.ssb.dlp.pseudo.service.pseudo;
22

33
import com.google.common.base.Stopwatch;
4-
import io.opentelemetry.api.GlobalOpenTelemetry;
5-
import io.opentelemetry.api.trace.Tracer;
6-
import io.opentelemetry.context.Scope;
7-
import io.opentelemetry.instrumentation.annotations.AddingSpanAttributes;
8-
import io.opentelemetry.instrumentation.annotations.SpanAttribute;
4+
import io.micronaut.tracing.annotation.NewSpan;
95
import io.reactivex.Completable;
106
import io.reactivex.Flowable;
117
import lombok.AccessLevel;
@@ -20,7 +16,6 @@
2016
import no.ssb.dlp.pseudo.core.util.Json;
2117
import no.ssb.dlp.pseudo.service.pseudo.metadata.FieldMetric;
2218
import no.ssb.dlp.pseudo.service.pseudo.metadata.PseudoMetadataProcessor;
23-
import no.ssb.dlp.pseudo.service.tracing.WithSpan;
2419

2520
import java.util.List;
2621
import java.util.Map;
@@ -87,7 +82,7 @@ public PseudoField(String name, String pattern, String pseudoFunc, EncryptedKeys
8782
* @param values The values to be processed.
8883
* @return A Flowable stream that processes the field values by applying the configured pseudo rules, and returns them as a lists of strings.
8984
*/
90-
@WithSpan
85+
@NewSpan
9186
public Flowable<String> process(PseudoConfigSplitter pseudoConfigSplitter,
9287
RecordMapProcessorFactory recordProcessorFactory,
9388
List<String> values,
@@ -137,7 +132,7 @@ public Flowable<String> process(PseudoConfigSplitter pseudoConfigSplitter,
137132
* @param values The values to be processed.
138133
* @return A Flowable stream that processes the field values by applying the configured pseudo rules, and returns them as a lists of strings.
139134
*/
140-
@WithSpan
135+
@NewSpan
141136
public Flowable<String> process(RecordMapProcessorFactory recordProcessorFactory,
142137
List<String> values,
143138
PseudoField targetPseudoField,

src/main/java/no/ssb/dlp/pseudo/service/pseudo/PseudoSecrets.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package no.ssb.dlp.pseudo.service.pseudo;
22

33
import io.micronaut.context.annotation.Property;
4+
import io.micronaut.tracing.annotation.NewSpan;
45
import jakarta.inject.Singleton;
56
import no.ssb.dlp.pseudo.core.PseudoSecret;
67
import no.ssb.dlp.pseudo.service.secrets.SecretService;
7-
import no.ssb.dlp.pseudo.service.tracing.WithSpan;
88

99
import java.util.List;
1010
import java.util.Map;
@@ -48,7 +48,7 @@ public List<PseudoSecret> resolve() {
4848
* @param configuredPseudoSecrets a Map named pseudo secrets
4949
* @return a List of cleaned up, resolved pseudo secrets
5050
*/
51-
@WithSpan
51+
@NewSpan
5252
List<PseudoSecret> resolvePseudoSecrets(Map<String, PseudoSecret> configuredPseudoSecrets) {
5353
if (configuredPseudoSecrets == null) {
5454
return List.of();

src/main/java/no/ssb/dlp/pseudo/service/pseudo/RecordMapProcessorFactory.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
import com.github.benmanes.caffeine.cache.LoadingCache;
44
import com.google.crypto.tink.Aead;
5+
import io.micronaut.tracing.annotation.NewSpan;
6+
import io.micronaut.tracing.annotation.SpanTag;
7+
import io.opentelemetry.api.trace.Span;
8+
import io.opentelemetry.api.trace.Tracer;
59
import jakarta.inject.Singleton;
610
import lombok.RequiredArgsConstructor;
711
import lombok.extern.slf4j.Slf4j;
@@ -28,8 +32,6 @@
2832
import no.ssb.dlp.pseudo.service.pseudo.metadata.FieldMetadata;
2933
import no.ssb.dlp.pseudo.service.pseudo.metadata.FieldMetric;
3034
import no.ssb.dlp.pseudo.service.pseudo.metadata.PseudoMetadataProcessor;
31-
import no.ssb.dlp.pseudo.service.tracing.SpanAttribute;
32-
import no.ssb.dlp.pseudo.service.tracing.WithSpan;
3335

3436
import java.util.Collection;
3537
import java.util.List;
@@ -47,9 +49,10 @@
4749
public class RecordMapProcessorFactory {
4850
private final PseudoSecrets pseudoSecrets;
4951
private final LoadingCache<String, Aead> aeadCache;
52+
private final Tracer tracer;
5053

51-
@WithSpan
52-
public RecordMapProcessor<PseudoMetadataProcessor> newPseudonymizeRecordProcessor(@SpanAttribute List<PseudoConfig> pseudoConfigs, String correlationId) {
54+
@NewSpan
55+
public RecordMapProcessor<PseudoMetadataProcessor> newPseudonymizeRecordProcessor(@SpanTag List<PseudoConfig> pseudoConfigs, String correlationId) {
5356
ValueInterceptorChain chain = new ValueInterceptorChain();
5457
PseudoMetadataProcessor metadataProcessor = new PseudoMetadataProcessor(correlationId);
5558

@@ -65,7 +68,7 @@ public RecordMapProcessor<PseudoMetadataProcessor> newPseudonymizeRecordProcesso
6568
return new RecordMapProcessor<>(chain, metadataProcessor);
6669
}
6770

68-
@WithSpan
71+
@NewSpan
6972
public RecordMapProcessor<PseudoMetadataProcessor> newDepseudonymizeRecordProcessor(List<PseudoConfig> pseudoConfigs, String correlationId) {
7073
ValueInterceptorChain chain = new ValueInterceptorChain();
7174
PseudoMetadataProcessor metadataProcessor = new PseudoMetadataProcessor(correlationId);
@@ -80,7 +83,7 @@ public RecordMapProcessor<PseudoMetadataProcessor> newDepseudonymizeRecordProces
8083
return new RecordMapProcessor<>(chain, metadataProcessor);
8184
}
8285

83-
@WithSpan
86+
@NewSpan
8487
public RecordMapProcessor<PseudoMetadataProcessor> newRepseudonymizeRecordProcessor(PseudoConfig sourcePseudoConfig,
8588
PseudoConfig targetPseudoConfig, String correlationId) {
8689
final PseudoFuncs fieldDepseudonymizer = newPseudoFuncs(sourcePseudoConfig.getRules(),
@@ -109,22 +112,24 @@ private String init(PseudoFuncs pseudoFuncs, TransformDirection direction, Field
109112
return varValue;
110113
}
111114

112-
@WithSpan
113-
protected String process(PseudoOperation operation,
115+
private String process(PseudoOperation operation,
114116
PseudoFuncs func,
115117
FieldDescriptor field,
116118
String varValue,
117119
PseudoMetadataProcessor metadataProcessor) {
120+
Span span = tracer.spanBuilder("process").startSpan();
118121
PseudoFuncRuleMatch match = func.findPseudoFunc(field).orElse(null);
119122

120123
if (match == null) {
124+
span.end();
121125
return varValue;
122126
}
123127
if (varValue == null) {
124128
// Avoid counting null values to map-sid twice (since map-sid consists of 2 functions)
125129
if (!(match.getFunc() instanceof MapFunc)) {
126130
metadataProcessor.addMetric(FieldMetric.NULL_VALUE);
127131
}
132+
span.end();
128133
return varValue;
129134
}
130135
try {
@@ -187,6 +192,8 @@ protected String process(PseudoOperation operation,
187192
} catch (Exception e) {
188193
throw new PseudoException(String.format("pseudonymize error - field='%s', originalValue='%s'",
189194
field.getPath(), varValue), e);
195+
} finally {
196+
span.end();
190197
}
191198
}
192199

0 commit comments

Comments
 (0)