From 747b7db06cc7490c01ad321d4c5030526c0140e5 Mon Sep 17 00:00:00 2001 From: Thiago Hora Date: Mon, 16 Sep 2024 15:56:38 +0200 Subject: [PATCH 01/10] [NA] Remove New Relic dependecy --- apps/opik-backend/config.yml | 3 ++ apps/opik-backend/entrypoint.sh | 10 +++--- apps/opik-backend/pom.xml | 22 ++++++++++-- .../java/com/comet/opik/OpikApplication.java | 3 +- .../com/comet/opik/domain/DatasetItemDAO.java | 35 +++++++++--------- .../comet/opik/domain/DatasetItemService.java | 14 ++++---- .../java/com/comet/opik/domain/SpanDAO.java | 36 +++++++++---------- .../com/comet/opik/domain/SpanService.java | 12 +++---- .../java/com/comet/opik/domain/TraceDAO.java | 17 ++++----- .../com/comet/opik/domain/TraceService.java | 15 ++++---- .../infrastructure/OpenTelemetryConfig.java | 13 +++++++ .../infrastructure/OpikConfiguration.java | 4 +++ .../instrumentation/InstrumentAsyncUtils.java | 28 +++++++++------ .../instrumentation/OpenTelemetryModule.java | 23 ++++++++++++ .../src/test/resources/config-test.yml | 3 ++ deployment/helm_chart/opik/values.yaml | 5 ++- 16 files changed, 159 insertions(+), 84 deletions(-) create mode 100644 apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpenTelemetryConfig.java create mode 100644 apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java diff --git a/apps/opik-backend/config.yml b/apps/opik-backend/config.yml index ec31499b02..728fdf1e40 100644 --- a/apps/opik-backend/config.yml +++ b/apps/opik-backend/config.yml @@ -65,3 +65,6 @@ server: enableVirtualThreads: ${ENABLE_VIRTUAL_THREADS:-false} gzip: enabled: true + +openTelemetry: + disabled: ${OTEL_SDK_DISABLED:-true} \ No newline at end of file diff --git a/apps/opik-backend/entrypoint.sh b/apps/opik-backend/entrypoint.sh index 140cc93987..629ec19eae 100644 --- a/apps/opik-backend/entrypoint.sh +++ b/apps/opik-backend/entrypoint.sh @@ -5,12 +5,12 @@ echo $(pwd) jwebserver -d /opt/opik/redoc -b 0.0.0.0 -p 3003 & echo "OPIK_VERSION=$OPIK_VERSION" -echo "NEW_RELIC_ENABLED=$NEW_RELIC_ENABLED" -echo "NEW_RELIC_VERSION=$NEW_RELIC_VERSION" +echo "OTEL_SDK_DISABLED=$OTEL_SDK_DISABLED" +echo "OTEL_VERSION=$OTEL_VERSION" -if [[ "${NEW_RELIC_ENABLED}" == "true" && "${NEW_RELIC_LICENSE_KEY}" != "" ]];then - curl -o /tmp/newrelic-agent.jar https://download.newrelic.com/newrelic/java-agent/newrelic-agent/${NEW_RELIC_VERSION}/newrelic-agent-${NEW_RELIC_VERSION}.jar - JAVA_OPTS="$JAVA_OPTS -javaagent:/tmp/newrelic-agent.jar" +if [[ "${OTEL_SDK_DISABLED}" == "false" ]];then + curl -L -o /tmp/opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v${OTEL_VERSION}/opentelemetry-javaagent.jar + JAVA_OPTS="$JAVA_OPTS -javaagent:/tmp/opentelemetry-javaagent.jar" fi # Check if ENABLE_VIRTUAL_THREADS is set to true diff --git a/apps/opik-backend/pom.xml b/apps/opik-backend/pom.xml index 9764160342..ca9efee01b 100644 --- a/apps/opik-backend/pom.xml +++ b/apps/opik-backend/pom.xml @@ -30,6 +30,7 @@ 5.1.0 3.9.1 3.34.1 + 1.42.1 com.comet.opik.OpikApplication @@ -49,14 +50,29 @@ pom import + + io.opentelemetry + opentelemetry-bom + ${opentelmetry.version} + pom + import + - com.newrelic.agent.java - newrelic-api - 8.14.0 + io.opentelemetry.instrumentation + opentelemetry-instrumentation-annotations + 2.8.0 + + + io.opentelemetry + opentelemetry-sdk + + + io.opentelemetry + opentelemetry-sdk-extension-autoconfigure io.dropwizard diff --git a/apps/opik-backend/src/main/java/com/comet/opik/OpikApplication.java b/apps/opik-backend/src/main/java/com/comet/opik/OpikApplication.java index 40248059ef..c1f267f56d 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/OpikApplication.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/OpikApplication.java @@ -5,6 +5,7 @@ import com.comet.opik.infrastructure.bundle.LiquibaseBundle; import com.comet.opik.infrastructure.db.DatabaseAnalyticsModule; import com.comet.opik.infrastructure.db.IdGeneratorModule; +import com.comet.opik.infrastructure.instrumentation.OpenTelemetryModule; import com.comet.opik.infrastructure.redis.RedisModule; import com.comet.opik.utils.JsonBigDecimalDeserializer; import com.fasterxml.jackson.annotation.JsonInclude; @@ -58,7 +59,7 @@ public void initialize(Bootstrap bootstrap) { bootstrap.addBundle(GuiceBundle.builder() .bundles(JdbiBundle.forDatabase((conf, env) -> conf.getDatabase()) .withPlugins(new SqlObjectPlugin(), new Jackson2Plugin())) - .modules(new DatabaseAnalyticsModule(), new IdGeneratorModule(), new AuthModule(), new RedisModule()) + .modules(new DatabaseAnalyticsModule(), new IdGeneratorModule(), new AuthModule(), new RedisModule(), new OpenTelemetryModule()) .enableAutoConfig() .build()); } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemDAO.java index e94abdad59..8b376553b8 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemDAO.java @@ -10,8 +10,7 @@ import com.comet.opik.utils.JsonUtils; import com.fasterxml.jackson.databind.JsonNode; import com.google.inject.ImplementedBy; -import com.newrelic.api.agent.Segment; -import com.newrelic.api.agent.Trace; +import io.opentelemetry.instrumentation.annotations.WithSpan; import io.r2dbc.spi.Connection; import io.r2dbc.spi.Result; import io.r2dbc.spi.Statement; @@ -38,6 +37,8 @@ import static com.comet.opik.api.DatasetItem.DatasetItemPage; import static com.comet.opik.domain.AsyncContextUtils.bindWorkspaceIdToFlux; +import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.Segment; +import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.endSegment; import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.startSegment; import static com.comet.opik.utils.AsyncUtils.makeFluxContextAware; import static com.comet.opik.utils.AsyncUtils.makeMonoContextAware; @@ -340,7 +341,7 @@ LEFT JOIN ( private final @NonNull TransactionTemplate asyncTemplate; @Override - @Trace(dispatcher = true) + @WithSpan public Mono save(@NonNull UUID datasetId, @NonNull List items) { if (items.isEmpty()) { @@ -387,7 +388,7 @@ private Mono mapAndInsert( return Flux.from(statement.execute()) .flatMap(Result::getRowsUpdated) .reduce(0L, Long::sum) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); }); } @@ -480,7 +481,7 @@ private List getFeedbackScores(Object feedbackScoresRaw) { } @Override - @Trace(dispatcher = true) + @WithSpan public Mono get(@NonNull UUID id) { return asyncTemplate.nonTransaction(connection -> { @@ -490,14 +491,14 @@ public Mono get(@NonNull UUID id) { Segment segment = startSegment("dataset_items", "Clickhouse", "select_dataset_item"); return makeFluxContextAware(bindWorkspaceIdToFlux(statement)) - .doFinally(signalType -> segment.end()) + .doFinally(signalType -> endSegment(segment)) .flatMap(this::mapItem) .singleOrEmpty(); }); } @Override - @Trace(dispatcher = true) + @WithSpan public Flux getItems(@NonNull UUID datasetId, int limit, UUID lastRetrievedId) { ST template = new ST(SELECT_DATASET_ITEMS_STREAM); @@ -518,13 +519,13 @@ public Flux getItems(@NonNull UUID datasetId, int limit, UUID lastR Segment segment = startSegment("dataset_items", "Clickhouse", "select_dataset_items_stream"); return makeFluxContextAware(bindWorkspaceIdToFlux(statement)) - .doFinally(signalType -> segment.end()) + .doFinally(signalType -> endSegment(segment)) .flatMap(this::mapItem); }); } @Override - @Trace(dispatcher = true) + @WithSpan public Mono> getDatasetItemWorkspace(@NonNull Set datasetItemIds) { if (datasetItemIds.isEmpty()) { @@ -545,7 +546,7 @@ public Mono> getDatasetItemWorkspace(@NonNull Set delete(@NonNull List ids) { if (ids.isEmpty()) { return Mono.empty(); @@ -560,7 +561,7 @@ public Mono delete(@NonNull List ids) { return bindAndDelete(ids, statement) .flatMap(Result::getRowsUpdated) .reduce(0L, Long::sum) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); }); } @@ -572,7 +573,7 @@ private Flux bindAndDelete(List ids, Statement statement } @Override - @Trace(dispatcher = true) + @WithSpan public Mono getItems(@NonNull UUID datasetId, int page, int size) { Segment segmentCount = startSegment("dataset_items", "Clickhouse", "select_dataset_items_page_count"); @@ -583,7 +584,7 @@ public Mono getItems(@NonNull UUID datasetId, int page, int siz .bind("datasetId", datasetId) .bind("workspace_id", workspaceId) .execute()) - .doFinally(signalType -> segmentCount.end()) + .doFinally(signalType -> endSegment(segmentCount)) .flatMap(result -> result.map((row, rowMetadata) -> row.get(0, Long.class))) .reduce(0L, Long::sum) .flatMap(count -> { @@ -599,12 +600,12 @@ public Mono getItems(@NonNull UUID datasetId, int page, int siz .flatMap(this::mapItem) .collectList() .flatMap(items -> Mono.just(new DatasetItemPage(items, page, items.size(), count))) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); }))); } @Override - @Trace(dispatcher = true) + @WithSpan public Mono getItems( @NonNull DatasetItemSearchCriteria datasetItemSearchCriteria, int page, int size) { log.info("Finding dataset items with experiment items by '{}', page '{}', size '{}'", @@ -621,7 +622,7 @@ public Mono getItems( .bind("experimentIds", datasetItemSearchCriteria.experimentIds()) .bind("workspace_id", workspaceId) .execute()) - .doFinally(signalType -> segmentCount.end()) + .doFinally(signalType -> endSegment(segmentCount)) .flatMap(result -> result.map((row, rowMetadata) -> row.get(0, Long.class))) .reduce(0L, Long::sum) .flatMap(count -> { @@ -639,7 +640,7 @@ public Mono getItems( .bind("limit", size) .bind("offset", (page - 1) * size) .execute()) - .doFinally(signalType -> segment.end()) + .doFinally(signalType -> endSegment(segment)) .flatMap(this::mapItem) .collectList() .flatMap(items -> Mono.just(new DatasetItemPage(items, page, items.size(), count))); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemService.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemService.java index da5b70fee9..b685ae876b 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemService.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemService.java @@ -8,7 +8,7 @@ import com.comet.opik.api.error.IdentifierMismatchException; import com.comet.opik.infrastructure.auth.RequestContext; import com.google.inject.ImplementedBy; -import com.newrelic.api.agent.Trace; +import io.opentelemetry.instrumentation.annotations.WithSpan; import jakarta.inject.Inject; import jakarta.inject.Singleton; import jakarta.ws.rs.ClientErrorException; @@ -57,7 +57,7 @@ class DatasetItemServiceImpl implements DatasetItemService { private final @NonNull SpanService spanService; @Override - @Trace(dispatcher = true) + @WithSpan public Mono save(@NonNull DatasetItemBatch batch) { if (batch.datasetId() == null && batch.datasetName() == null) { return Mono.error(failWithError("dataset_id or dataset_name must be provided")); @@ -102,14 +102,14 @@ private ClientErrorException newConflict(String error) { } @Override - @Trace(dispatcher = true) + @WithSpan public Mono get(@NonNull UUID id) { return dao.get(id) .switchIfEmpty(Mono.defer(() -> Mono.error(failWithNotFound("Dataset item not found")))); } @Override - @Trace(dispatcher = true) + @WithSpan public Flux getItems(@NonNull UUID datasetId, int limit, UUID lastRetrievedId) { return dao.getItems(datasetId, limit, lastRetrievedId); } @@ -185,7 +185,7 @@ private NotFoundException failWithNotFound(String message) { } @Override - @Trace(dispatcher = true) + @WithSpan public Mono delete(@NonNull List ids) { if (ids.isEmpty()) { return Mono.empty(); @@ -195,13 +195,13 @@ public Mono delete(@NonNull List ids) { } @Override - @Trace(dispatcher = true) + @WithSpan public Mono getItems(@NonNull UUID datasetId, int page, int size) { return dao.getItems(datasetId, page, size); } @Override - @Trace(dispatcher = true) + @WithSpan public Mono getItems( int page, int size, @NonNull DatasetItemSearchCriteria datasetItemSearchCriteria) { log.info("Finding dataset items with experiment items by '{}', page '{}', size '{}'", diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanDAO.java index 0a6a9daa4e..f3d1e37c46 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanDAO.java @@ -8,8 +8,7 @@ import com.comet.opik.utils.JsonUtils; import com.comet.opik.utils.TemplateUtils; import com.google.common.base.Preconditions; -import com.newrelic.api.agent.Segment; -import com.newrelic.api.agent.Trace; +import io.opentelemetry.instrumentation.annotations.WithSpan; import io.r2dbc.spi.Connection; import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.Result; @@ -38,6 +37,7 @@ import static com.comet.opik.domain.AsyncContextUtils.bindWorkspaceIdToFlux; import static com.comet.opik.domain.AsyncContextUtils.bindWorkspaceIdToMono; import static com.comet.opik.domain.FeedbackScoreDAO.EntityType; +import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.Segment; import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.endSegment; import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.startSegment; import static com.comet.opik.utils.AsyncUtils.makeFluxContextAware; @@ -484,14 +484,14 @@ AND id in ( private final @NonNull FeedbackScoreDAO feedbackScoreDAO; private final @NonNull FilterQueryBuilder filterQueryBuilder; - @Trace(dispatcher = true) + @WithSpan public Mono insert(@NonNull Span span) { return Mono.from(connectionFactory.create()) .flatMapMany(connection -> insert(span, connection)) .then(); } - @Trace(dispatcher = true) + @WithSpan public Mono batchInsert(@NonNull List spans) { Preconditions.checkArgument(!spans.isEmpty(), "Spans list must not be empty"); @@ -620,7 +620,7 @@ private Publisher insert(Span span, Connection connection) { Segment segment = startSegment("spans", "Clickhouse", "insert"); return makeFluxContextAware(bindUserNameAndWorkspaceContextToStream(statement)) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); } private ST newInsertTemplate(Span span) { @@ -630,7 +630,7 @@ private ST newInsertTemplate(Span span) { return template; } - @Trace(dispatcher = true) + @WithSpan public Mono update(@NonNull UUID id, @NonNull SpanUpdate spanUpdate) { return Mono.from(connectionFactory.create()) .flatMapMany(connection -> update(id, spanUpdate, connection)) @@ -638,7 +638,7 @@ public Mono update(@NonNull UUID id, @NonNull SpanUpdate spanUpdate) { .reduce(0L, Long::sum); } - @Trace(dispatcher = true) + @WithSpan public Mono partialInsert(@NonNull UUID id, @NonNull UUID projectId, @NonNull SpanUpdate spanUpdate) { return Mono.from(connectionFactory.create()) .flatMapMany(connection -> { @@ -661,7 +661,7 @@ public Mono partialInsert(@NonNull UUID id, @NonNull UUID projectId, @NonN Segment segment = startSegment("spans", "Clickhouse", "partial_insert"); return makeFluxContextAware(bindUserNameAndWorkspaceContextToStream(statement)) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); }) .flatMap(Result::getRowsUpdated) .reduce(0L, Long::sum); @@ -676,7 +676,7 @@ private Publisher update(UUID id, SpanUpdate spanUpdate, Conne Segment segment = startSegment("spans", "Clickhouse", "update"); return makeFluxContextAware(bindUserNameAndWorkspaceContextToStream(statement)) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); } private void bindUpdateParams(SpanUpdate spanUpdate, Statement statement) { @@ -721,7 +721,7 @@ private ST newUpdateTemplate(SpanUpdate spanUpdate, String sql) { return template; } - @Trace(dispatcher = true) + @WithSpan public Mono getById(@NonNull UUID id) { log.info("Getting span by id '{}'", id); return Mono.from(connectionFactory.create()) @@ -740,10 +740,10 @@ private Publisher getById(UUID id, Connection connection) { Segment segment = startSegment("spans", "Clickhouse", "get_by_id"); return makeFluxContextAware(bindWorkspaceIdToFlux(statement)) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); } - @Trace(dispatcher = true) + @WithSpan public Mono deleteByTraceId(@NonNull UUID traceId, @NonNull Connection connection) { Statement statement = connection.createStatement(DELETE_BY_TRACE_ID) .bind("trace_id", traceId); @@ -751,7 +751,7 @@ public Mono deleteByTraceId(@NonNull UUID traceId, @NonNull Connection con Segment segment = startSegment("spans", "Clickhouse", "delete_by_trace_id"); return makeMonoContextAware(bindWorkspaceIdToMono(statement)) - .doFinally(signalType -> segment.end()) + .doFinally(signalType -> endSegment(segment)) .then(); } @@ -795,7 +795,7 @@ private Publisher mapToDto(Result result) { }); } - @Trace(dispatcher = true) + @WithSpan public Mono find(int page, int size, @NonNull SpanSearchCriteria spanSearchCriteria) { log.info("Finding span by '{}'", spanSearchCriteria); return countTotal(spanSearchCriteria).flatMap(total -> find(page, size, spanSearchCriteria, total)); @@ -820,7 +820,7 @@ private Mono> enhanceWithFeedbackScores(List spans, Connection .map(scoresMap -> spans.stream() .map(span -> span.toBuilder().feedbackScores(scoresMap.get(span.id())).build()) .toList()) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); } private Publisher find(int page, int size, SpanSearchCriteria spanSearchCriteria, @@ -837,7 +837,7 @@ private Publisher find(int page, int size, SpanSearchCriteria Segment segment = startSegment("spans", "Clickhouse", "find"); return makeFluxContextAware(bindWorkspaceIdToFlux(statement)) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); } private Mono countTotal(SpanSearchCriteria spanSearchCriteria) { @@ -857,7 +857,7 @@ private Publisher countTotal(SpanSearchCriteria spanSearchCrit Segment segment = startSegment("spans", "Clickhouse", "count_total"); return makeFluxContextAware(bindWorkspaceIdToFlux(statement)) - .doFinally(signalType -> segment.end()); + .doFinally(signalType -> endSegment(segment)); } private ST newFindTemplate(String query, SpanSearchCriteria spanSearchCriteria) { @@ -888,7 +888,7 @@ private void bindSearchCriteria(Statement statement, SpanSearchCriteria spanSear }); } - @Trace(dispatcher = true) + @WithSpan public Mono> getSpanWorkspace(@NonNull Set spanIds) { if (spanIds.isEmpty()) { return Mono.just(List.of()); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanService.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanService.java index 27caa0053f..a98a6bb99e 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanService.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanService.java @@ -13,7 +13,7 @@ import com.comet.opik.infrastructure.redis.LockService; import com.comet.opik.utils.WorkspaceUtils; import com.google.common.base.Preconditions; -import com.newrelic.api.agent.Trace; +import io.opentelemetry.instrumentation.annotations.WithSpan; import jakarta.inject.Inject; import jakarta.inject.Singleton; import jakarta.ws.rs.NotFoundException; @@ -50,7 +50,7 @@ public class SpanService { private final @NonNull IdGenerator idGenerator; private final @NonNull LockService lockService; - @Trace(dispatcher = true) + @WithSpan public Mono find(int page, int size, @NonNull SpanSearchCriteria searchCriteria) { log.info("Finding span by '{}'", searchCriteria); @@ -75,13 +75,13 @@ private Mono> findProject(SpanSearchCriteria searchCriteria) { }); } - @Trace(dispatcher = true) + @WithSpan public Mono getById(@NonNull UUID id) { log.info("Getting span by id '{}'", id); return spanDAO.getById(id).switchIfEmpty(Mono.defer(() -> Mono.error(newNotFoundException(id)))); } - @Trace(dispatcher = true) + @WithSpan public Mono create(@NonNull Span span) { var id = span.id() == null ? idGenerator.generateId() : span.id(); var projectName = WorkspaceUtils.getProjectName(span.projectName()); @@ -158,7 +158,7 @@ private Mono handleProjectCreationError(Throwable exception, String pro }; } - @Trace(dispatcher = true) + @WithSpan public Mono update(@NonNull UUID id, @NonNull SpanUpdate spanUpdate) { log.info("Updating span with id '{}'", id); @@ -254,7 +254,7 @@ public Mono validateSpanWorkspace(@NonNull String workspaceId, @NonNull .map(spanWorkspace -> spanWorkspace.stream().allMatch(span -> workspaceId.equals(span.workspaceId()))); } - @Trace(dispatcher = true) + @WithSpan public Mono create(@NonNull SpanBatch batch) { Preconditions.checkArgument(!batch.spans().isEmpty(), "Batch spans must not be empty"); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceDAO.java index 5a054f3245..4129de092d 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceDAO.java @@ -10,7 +10,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.Preconditions; import com.google.inject.ImplementedBy; -import com.newrelic.api.agent.Segment; +import io.opentelemetry.instrumentation.annotations.WithSpan; import io.r2dbc.spi.Connection; import io.r2dbc.spi.Result; import io.r2dbc.spi.Statement; @@ -37,6 +37,7 @@ import static com.comet.opik.domain.AsyncContextUtils.bindWorkspaceIdToFlux; import static com.comet.opik.domain.AsyncContextUtils.bindWorkspaceIdToMono; import static com.comet.opik.domain.FeedbackScoreDAO.EntityType; +import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.Segment; import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.endSegment; import static com.comet.opik.infrastructure.instrumentation.InstrumentAsyncUtils.startSegment; import static com.comet.opik.utils.AsyncUtils.makeFluxContextAware; @@ -423,7 +424,7 @@ LEFT JOIN ( private final @NonNull FilterQueryBuilder filterQueryBuilder; @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono insert(@NonNull Trace trace, @NonNull Connection connection) { ST template = buildInsertTemplate(trace); @@ -486,7 +487,7 @@ private ST buildInsertTemplate(Trace trace) { } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono update(@NonNull TraceUpdate traceUpdate, @NonNull UUID id, @NonNull Connection connection) { return update(id, traceUpdate, connection).then(); } @@ -564,7 +565,7 @@ private Flux getById(UUID id, Connection connection) { } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono delete(@NonNull UUID id, @NonNull Connection connection) { var statement = connection.createStatement(DELETE_BY_ID) .bind("id", id); @@ -577,7 +578,7 @@ public Mono delete(@NonNull UUID id, @NonNull Connection connection) { } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono findById(@NonNull UUID id, @NonNull Connection connection) { return getById(id, connection) .flatMap(this::mapToDto) @@ -617,7 +618,7 @@ private Publisher mapToDto(Result result) { } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono find( int size, int page, @NonNull TraceSearchCriteria traceSearchCriteria, @NonNull Connection connection) { return countTotal(traceSearchCriteria, connection) @@ -630,7 +631,7 @@ public Mono find( } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono partialInsert( @NonNull UUID projectId, @NonNull TraceUpdate traceUpdate, @@ -714,7 +715,7 @@ private void bindSearchCriteria(TraceSearchCriteria traceSearchCriteria, Stateme } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono> getTraceWorkspace( @NonNull Set traceIds, @NonNull Connection connection) { diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java index 1b3b70a556..083787ef53 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java @@ -16,6 +16,7 @@ import com.comet.opik.utils.WorkspaceUtils; import com.google.common.base.Preconditions; import com.google.inject.ImplementedBy; +import io.opentelemetry.instrumentation.annotations.WithSpan; import jakarta.inject.Inject; import jakarta.inject.Singleton; import jakarta.ws.rs.NotFoundException; @@ -73,7 +74,7 @@ class TraceServiceImpl implements TraceService { private final @NonNull LockService lockService; @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono create(@NonNull Trace trace) { String projectName = WorkspaceUtils.getProjectName(trace.projectName()); @@ -87,7 +88,7 @@ public Mono create(@NonNull Trace trace) { Mono.defer(() -> insertTrace(trace, project, id)))); } - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono create(TraceBatch batch) { Preconditions.checkArgument(!batch.traces().isEmpty(), "Batch traces cannot be empty"); @@ -209,7 +210,7 @@ private Mono handleProjectCreationError(Throwable exception, String pro } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono update(@NonNull TraceUpdate traceUpdate, @NonNull UUID id) { var projectName = WorkspaceUtils.getProjectName(traceUpdate.projectName()); @@ -263,14 +264,14 @@ private NotFoundException failWithNotFound(String error) { } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono get(@NonNull UUID id) { return template.nonTransaction(connection -> dao.findById(id, connection)) .switchIfEmpty(Mono.defer(() -> Mono.error(failWithNotFound("Trace not found")))); } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono delete(@NonNull UUID id) { return lockService.executeWithLock( new LockService.Lock(id, TRACE_KEY), @@ -283,7 +284,7 @@ public Mono delete(@NonNull UUID id) { } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono find(int page, int size, @NonNull TraceSearchCriteria criteria) { if (criteria.projectId() != null) { @@ -297,7 +298,7 @@ public Mono find(int page, int size, @NonNull TraceSearchCriter } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono validateTraceWorkspace(@NonNull String workspaceId, @NonNull Set traceIds) { if (traceIds.isEmpty()) { return Mono.just(true); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpenTelemetryConfig.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpenTelemetryConfig.java new file mode 100644 index 0000000000..a5b779aecc --- /dev/null +++ b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpenTelemetryConfig.java @@ -0,0 +1,13 @@ +package com.comet.opik.infrastructure; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.Valid; +import lombok.Data; + +@Data +public class OpenTelemetryConfig { + + @Valid + @JsonProperty + private boolean disabled; +} diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpikConfiguration.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpikConfiguration.java index 754a685ade..28fc8d580e 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpikConfiguration.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpikConfiguration.java @@ -33,4 +33,8 @@ public class OpikConfiguration extends Configuration { @Valid @NotNull @JsonProperty private DistributedLockConfig distributedLock = new DistributedLockConfig(); + + @Valid + @NotNull @JsonProperty + private OpenTelemetryConfig openTelemetry = new OpenTelemetryConfig(); } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/InstrumentAsyncUtils.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/InstrumentAsyncUtils.java index 0ba6e20572..c0d0007dbb 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/InstrumentAsyncUtils.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/InstrumentAsyncUtils.java @@ -1,8 +1,10 @@ package com.comet.opik.infrastructure.instrumentation; -import com.newrelic.api.agent.DatastoreParameters; -import com.newrelic.api.agent.NewRelic; -import com.newrelic.api.agent.Segment; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; import reactor.core.scheduler.Schedulers; @@ -11,17 +13,20 @@ @UtilityClass public class InstrumentAsyncUtils { + public record Segment(Scope scope, Span span) {} + public static Segment startSegment(String segmentName, String product, String operationName) { - Segment segment = NewRelic.getAgent().getTransaction().startSegment(segmentName); + Tracer tracer = GlobalOpenTelemetry.get().getTracer("com.comet.opik"); - segment.reportAsExternal(DatastoreParameters - .product(product) - .collection(null) - .operation(operationName) - .build()); + Span span = tracer + .spanBuilder("custom-reactive-%s".formatted(segmentName)) + .setParent(Context.current().with(Span.current())) + .startSpan() + .setAttribute("product", product) + .setAttribute("operation", operationName); - return segment; + return new Segment(span.makeCurrent(), span); } public static void endSegment(Segment segment) { @@ -30,7 +35,8 @@ public static void endSegment(Segment segment) { Schedulers.boundedElastic().schedule(() -> { try { // End the segment - segment.end(); + segment.scope().close(); + segment.span().end(); } catch (Exception e) { log.warn("Failed to end segment", e); } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java new file mode 100644 index 0000000000..5bb039f529 --- /dev/null +++ b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java @@ -0,0 +1,23 @@ +package com.comet.opik.infrastructure.instrumentation; + +import com.comet.opik.infrastructure.OpenTelemetryConfig; +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import jakarta.inject.Singleton; +import ru.vyarus.dropwizard.guice.module.yaml.bind.Config; + +public class OpenTelemetryModule extends AbstractModule { + + @Provides + @Singleton + public OpenTelemetry openTelemetry(@Config("openTelemetry") OpenTelemetryConfig config) { + + if (config.isDisabled()) { + return OpenTelemetry.noop(); + } + + return AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk(); + } +} diff --git a/apps/opik-backend/src/test/resources/config-test.yml b/apps/opik-backend/src/test/resources/config-test.yml index 412ecf9cd5..457004fcaf 100644 --- a/apps/opik-backend/src/test/resources/config-test.yml +++ b/apps/opik-backend/src/test/resources/config-test.yml @@ -65,3 +65,6 @@ server: enableVirtualThreads: ${ENABLE_VIRTUAL_THREADS:-false} gzip: enabled: true + +openTelemetry: + disabled: ${OTEL_SDK_DISABLED:-true} \ No newline at end of file diff --git a/deployment/helm_chart/opik/values.yaml b/deployment/helm_chart/opik/values.yaml index 7746e7ee2f..ac52488dbf 100644 --- a/deployment/helm_chart/opik/values.yaml +++ b/deployment/helm_chart/opik/values.yaml @@ -55,7 +55,10 @@ component: ANALYTICS_DB_MIGRATIONS_PASS: opik ANALYTICS_DB_PASS: opik STATE_DB_PASS: opik - + OTEL_RESOURCE_ATTRIBUTES: "service.name=opik-backend,service.version=$OPIK_VERSION" + OTEL_TRACES_EXPORTER: otlp + OTEL_SDK_DISABLED: true + OTEL_VERSION: 2.8.0 envFrom: - configMapRef: name: opik-backend From 24eeb3113d313d59f4a1ed772ad65d75adb8c377 Mon Sep 17 00:00:00 2001 From: CometActions Date: Mon, 16 Sep 2024 13:58:06 +0000 Subject: [PATCH 02/10] Update Helm documentation --- deployment/helm_chart/opik/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deployment/helm_chart/opik/README.md b/deployment/helm_chart/opik/README.md index de0cd2bb7b..f054ed7b82 100644 --- a/deployment/helm_chart/opik/README.md +++ b/deployment/helm_chart/opik/README.md @@ -109,6 +109,10 @@ Call opik api on http://localhost:5173/api | component.backend.env.ANALYTICS_DB_PROTOCOL | string | `"HTTP"` | | | component.backend.env.ANALYTICS_DB_USERNAME | string | `"opik"` | | | component.backend.env.JAVA_OPTS | string | `"-Dliquibase.propertySubstitutionEnabled=true"` | | +| component.backend.env.OTEL_RESOURCE_ATTRIBUTES | string | `"service.name=opik-backend,service.version=$OPIK_VERSION"` | | +| component.backend.env.OTEL_SDK_DISABLED | bool | `true` | | +| component.backend.env.OTEL_TRACES_EXPORTER | string | `"otlp"` | | +| component.backend.env.OTEL_VERSION | string | `"2.8.0"` | | | component.backend.env.REDIS_URL | string | `"redis://:wFSuJX9nDBdCa25sKZG7bh@opik-redis-master:6379/"` | | | component.backend.env.STATE_DB_DATABASE_NAME | string | `"opik"` | | | component.backend.env.STATE_DB_PASS | string | `"opik"` | | From 136300158ea6acc19b73bd6dffd69c7fe7860baa Mon Sep 17 00:00:00 2001 From: Thiago Hora Date: Mon, 16 Sep 2024 19:05:56 +0200 Subject: [PATCH 03/10] Fix versions --- apps/opik-backend/pom.xml | 19 ++----------------- .../instrumentation/OpenTelemetryModule.java | 4 ++-- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/apps/opik-backend/pom.xml b/apps/opik-backend/pom.xml index ca9efee01b..d2fc17d859 100644 --- a/apps/opik-backend/pom.xml +++ b/apps/opik-backend/pom.xml @@ -30,7 +30,7 @@ 5.1.0 3.9.1 3.34.1 - 1.42.1 + 2.8.0 com.comet.opik.OpikApplication @@ -50,13 +50,6 @@ pom import - - io.opentelemetry - opentelemetry-bom - ${opentelmetry.version} - pom - import - @@ -64,15 +57,7 @@ io.opentelemetry.instrumentation opentelemetry-instrumentation-annotations - 2.8.0 - - - io.opentelemetry - opentelemetry-sdk - - - io.opentelemetry - opentelemetry-sdk-extension-autoconfigure + ${opentelmetry.version} io.dropwizard diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java index 5bb039f529..f5445345df 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java @@ -3,8 +3,8 @@ import com.comet.opik.infrastructure.OpenTelemetryConfig; import com.google.inject.AbstractModule; import com.google.inject.Provides; +import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import jakarta.inject.Singleton; import ru.vyarus.dropwizard.guice.module.yaml.bind.Config; @@ -18,6 +18,6 @@ public OpenTelemetry openTelemetry(@Config("openTelemetry") OpenTelemetryConfig return OpenTelemetry.noop(); } - return AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk(); + return GlobalOpenTelemetry.get(); } } From 789eb7421e123e14df26683a344de4250a14fe4d Mon Sep 17 00:00:00 2001 From: Thiago Hora Date: Tue, 17 Sep 2024 22:54:33 +0200 Subject: [PATCH 04/10] Fix setup --- apps/opik-backend/config.yml | 3 --- apps/opik-backend/entrypoint.sh | 5 ++-- apps/opik-backend/pom.xml | 5 ++++ .../java/com/comet/opik/OpikApplication.java | 3 +-- .../java/com/comet/opik/domain/SpanDAO.java | 2 +- .../java/com/comet/opik/domain/TraceDAO.java | 2 +- .../com/comet/opik/domain/TraceService.java | 1 - .../infrastructure/OpenTelemetryConfig.java | 13 ----------- .../infrastructure/OpikConfiguration.java | 3 --- .../db/DatabaseAnalyticsModule.java | 7 +++++- .../instrumentation/OpenTelemetryModule.java | 23 ------------------- .../src/test/resources/config-test.yml | 3 --- deployment/docker-compose/docker-compose.yaml | 4 ++++ deployment/helm_chart/opik/values.yaml | 9 +++++--- 14 files changed, 27 insertions(+), 56 deletions(-) delete mode 100644 apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpenTelemetryConfig.java delete mode 100644 apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java diff --git a/apps/opik-backend/config.yml b/apps/opik-backend/config.yml index 728fdf1e40..ec31499b02 100644 --- a/apps/opik-backend/config.yml +++ b/apps/opik-backend/config.yml @@ -65,6 +65,3 @@ server: enableVirtualThreads: ${ENABLE_VIRTUAL_THREADS:-false} gzip: enabled: true - -openTelemetry: - disabled: ${OTEL_SDK_DISABLED:-true} \ No newline at end of file diff --git a/apps/opik-backend/entrypoint.sh b/apps/opik-backend/entrypoint.sh index 629ec19eae..3dbb72594b 100644 --- a/apps/opik-backend/entrypoint.sh +++ b/apps/opik-backend/entrypoint.sh @@ -5,10 +5,11 @@ echo $(pwd) jwebserver -d /opt/opik/redoc -b 0.0.0.0 -p 3003 & echo "OPIK_VERSION=$OPIK_VERSION" -echo "OTEL_SDK_DISABLED=$OTEL_SDK_DISABLED" +echo "OPIK_OTEL_SDK_ENABLED=$OPIK_OTEL_SDK_ENABLED" echo "OTEL_VERSION=$OTEL_VERSION" -if [[ "${OTEL_SDK_DISABLED}" == "false" ]];then +if [[ "${OPIK_OTEL_SDK_ENABLED}" == "true" && "${OTEL_VERSION}" != "" && "${OTEL_EXPORTER_OTLP_ENDPOINT}" != "" ]];then + OTEL_RESOURCE_ATTRIBUTES="service.name=opik-backend,service.version=${OPIK_VERSION}" curl -L -o /tmp/opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v${OTEL_VERSION}/opentelemetry-javaagent.jar JAVA_OPTS="$JAVA_OPTS -javaagent:/tmp/opentelemetry-javaagent.jar" fi diff --git a/apps/opik-backend/pom.xml b/apps/opik-backend/pom.xml index d2fc17d859..47821455f5 100644 --- a/apps/opik-backend/pom.xml +++ b/apps/opik-backend/pom.xml @@ -59,6 +59,11 @@ opentelemetry-instrumentation-annotations ${opentelmetry.version} + + io.opentelemetry.instrumentation + opentelemetry-r2dbc-1.0 + ${opentelmetry.version}-alpha + io.dropwizard dropwizard-core diff --git a/apps/opik-backend/src/main/java/com/comet/opik/OpikApplication.java b/apps/opik-backend/src/main/java/com/comet/opik/OpikApplication.java index c1f267f56d..40248059ef 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/OpikApplication.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/OpikApplication.java @@ -5,7 +5,6 @@ import com.comet.opik.infrastructure.bundle.LiquibaseBundle; import com.comet.opik.infrastructure.db.DatabaseAnalyticsModule; import com.comet.opik.infrastructure.db.IdGeneratorModule; -import com.comet.opik.infrastructure.instrumentation.OpenTelemetryModule; import com.comet.opik.infrastructure.redis.RedisModule; import com.comet.opik.utils.JsonBigDecimalDeserializer; import com.fasterxml.jackson.annotation.JsonInclude; @@ -59,7 +58,7 @@ public void initialize(Bootstrap bootstrap) { bootstrap.addBundle(GuiceBundle.builder() .bundles(JdbiBundle.forDatabase((conf, env) -> conf.getDatabase()) .withPlugins(new SqlObjectPlugin(), new Jackson2Plugin())) - .modules(new DatabaseAnalyticsModule(), new IdGeneratorModule(), new AuthModule(), new RedisModule(), new OpenTelemetryModule()) + .modules(new DatabaseAnalyticsModule(), new IdGeneratorModule(), new AuthModule(), new RedisModule()) .enableAutoConfig() .build()); } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanDAO.java index 8977cba042..c130c32453 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/SpanDAO.java @@ -748,7 +748,7 @@ public Mono deleteByTraceId(@NonNull UUID traceId, @NonNull Connection con return deleteByTraceIds(Set.of(traceId), connection); } - @Trace(dispatcher = true) + @WithSpan public Mono deleteByTraceIds(Set traceIds, @NonNull Connection connection) { Preconditions.checkArgument( CollectionUtils.isNotEmpty(traceIds), "Argument 'traceIds' must not be empty"); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceDAO.java index f915f89cce..c02cc68fcc 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceDAO.java @@ -811,7 +811,7 @@ private String getOrDefault(JsonNode value) { return value != null ? value.toString() : ""; } - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Flux countTracesPerWorkspace(Connection connection) { var statement = connection.createStatement(TRACE_COUNT_BY_WORKSPACE_ID); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java index fe25edee17..2c7009b946 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java @@ -291,7 +291,6 @@ public Mono delete(@NonNull UUID id) { @Override @WithSpan - @com.newrelic.api.agent.Trace(dispatcher = true) public Mono delete(Set ids) { Preconditions.checkArgument(CollectionUtils.isNotEmpty(ids), "Argument 'ids' must not be empty"); log.info("Deleting traces, count '{}'", ids.size()); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpenTelemetryConfig.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpenTelemetryConfig.java deleted file mode 100644 index a5b779aecc..0000000000 --- a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpenTelemetryConfig.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.comet.opik.infrastructure; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import lombok.Data; - -@Data -public class OpenTelemetryConfig { - - @Valid - @JsonProperty - private boolean disabled; -} diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpikConfiguration.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpikConfiguration.java index 28fc8d580e..defcd3b313 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpikConfiguration.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/OpikConfiguration.java @@ -34,7 +34,4 @@ public class OpikConfiguration extends Configuration { @NotNull @JsonProperty private DistributedLockConfig distributedLock = new DistributedLockConfig(); - @Valid - @NotNull @JsonProperty - private OpenTelemetryConfig openTelemetry = new OpenTelemetryConfig(); } diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/db/DatabaseAnalyticsModule.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/db/DatabaseAnalyticsModule.java index ce164a384f..0b93e4dea4 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/db/DatabaseAnalyticsModule.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/db/DatabaseAnalyticsModule.java @@ -3,7 +3,11 @@ import com.comet.opik.infrastructure.DatabaseAnalyticsFactory; import com.comet.opik.infrastructure.OpikConfiguration; import com.google.inject.Provides; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.r2dbc.v1_0.R2dbcTelemetry; import io.r2dbc.spi.ConnectionFactory; +import io.r2dbc.spi.ConnectionFactoryOptions; import jakarta.inject.Named; import jakarta.inject.Singleton; import ru.vyarus.dropwizard.guice.module.support.DropwizardAwareModule; @@ -22,7 +26,8 @@ protected void configure() { @Provides @Singleton public ConnectionFactory getConnectionFactory() { - return connectionFactory; + return R2dbcTelemetry.create(GlobalOpenTelemetry.get()) + .wrapConnectionFactory(connectionFactory, ConnectionFactoryOptions.builder().build()); } @Provides diff --git a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java b/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java deleted file mode 100644 index f5445345df..0000000000 --- a/apps/opik-backend/src/main/java/com/comet/opik/infrastructure/instrumentation/OpenTelemetryModule.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.comet.opik.infrastructure.instrumentation; - -import com.comet.opik.infrastructure.OpenTelemetryConfig; -import com.google.inject.AbstractModule; -import com.google.inject.Provides; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.OpenTelemetry; -import jakarta.inject.Singleton; -import ru.vyarus.dropwizard.guice.module.yaml.bind.Config; - -public class OpenTelemetryModule extends AbstractModule { - - @Provides - @Singleton - public OpenTelemetry openTelemetry(@Config("openTelemetry") OpenTelemetryConfig config) { - - if (config.isDisabled()) { - return OpenTelemetry.noop(); - } - - return GlobalOpenTelemetry.get(); - } -} diff --git a/apps/opik-backend/src/test/resources/config-test.yml b/apps/opik-backend/src/test/resources/config-test.yml index 457004fcaf..412ecf9cd5 100644 --- a/apps/opik-backend/src/test/resources/config-test.yml +++ b/apps/opik-backend/src/test/resources/config-test.yml @@ -65,6 +65,3 @@ server: enableVirtualThreads: ${ENABLE_VIRTUAL_THREADS:-false} gzip: enabled: true - -openTelemetry: - disabled: ${OTEL_SDK_DISABLED:-true} \ No newline at end of file diff --git a/deployment/docker-compose/docker-compose.yaml b/deployment/docker-compose/docker-compose.yaml index a065fe136e..c970afdc52 100644 --- a/deployment/docker-compose/docker-compose.yaml +++ b/deployment/docker-compose/docker-compose.yaml @@ -81,6 +81,10 @@ services: JAVA_OPTS: "-Dliquibase.propertySubstitutionEnabled=true" REDIS_URL: redis://:opik@redis:6379/ ANALYTICS_DB_PASS: opik + OTEL_RESOURCE_ATTRIBUTES: "service.name=opik-backend,service.version=$OPIK_VERSION" + OTEL_TRACES_EXPORTER: otlp + OPIK_OTEL_SDK_ENABLED: false + OTEL_VERSION: 2.8.0 ports: - "8080:8080" - "3003:3003" diff --git a/deployment/helm_chart/opik/values.yaml b/deployment/helm_chart/opik/values.yaml index ac52488dbf..4b1d55b774 100644 --- a/deployment/helm_chart/opik/values.yaml +++ b/deployment/helm_chart/opik/values.yaml @@ -55,10 +55,13 @@ component: ANALYTICS_DB_MIGRATIONS_PASS: opik ANALYTICS_DB_PASS: opik STATE_DB_PASS: opik - OTEL_RESOURCE_ATTRIBUTES: "service.name=opik-backend,service.version=$OPIK_VERSION" - OTEL_TRACES_EXPORTER: otlp - OTEL_SDK_DISABLED: true + OPIK_OTEL_SDK_ENABLED: false OTEL_VERSION: 2.8.0 + OTEL_PROPAGATORS: "tracecontext,baggage,b3" + OTEL_EXPERIMENTAL_EXPORTER_OTLP_RETRY_ENABLED: true + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION: BASE2_EXPONENTIAL_BUCKET_HISTOGRAM + OTEL_EXPERIMENTAL_RESOURCE_DISABLED_KEYS: process.command_args + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE: delta envFrom: - configMapRef: name: opik-backend From 425a1672a4b213dc01b2835c3bd26471d3f3490a Mon Sep 17 00:00:00 2001 From: CometActions Date: Wed, 18 Sep 2024 13:56:30 +0000 Subject: [PATCH 05/10] Update Helm documentation --- deployment/helm_chart/opik/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/deployment/helm_chart/opik/README.md b/deployment/helm_chart/opik/README.md index f054ed7b82..e19dfcb47d 100644 --- a/deployment/helm_chart/opik/README.md +++ b/deployment/helm_chart/opik/README.md @@ -109,9 +109,12 @@ Call opik api on http://localhost:5173/api | component.backend.env.ANALYTICS_DB_PROTOCOL | string | `"HTTP"` | | | component.backend.env.ANALYTICS_DB_USERNAME | string | `"opik"` | | | component.backend.env.JAVA_OPTS | string | `"-Dliquibase.propertySubstitutionEnabled=true"` | | -| component.backend.env.OTEL_RESOURCE_ATTRIBUTES | string | `"service.name=opik-backend,service.version=$OPIK_VERSION"` | | -| component.backend.env.OTEL_SDK_DISABLED | bool | `true` | | -| component.backend.env.OTEL_TRACES_EXPORTER | string | `"otlp"` | | +| component.backend.env.OPIK_OTEL_SDK_ENABLED | bool | `false` | | +| component.backend.env.OTEL_EXPERIMENTAL_EXPORTER_OTLP_RETRY_ENABLED | bool | `true` | | +| component.backend.env.OTEL_EXPERIMENTAL_RESOURCE_DISABLED_KEYS | string | `"process.command_args"` | | +| component.backend.env.OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION | string | `"BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"` | | +| component.backend.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | string | `"delta"` | | +| component.backend.env.OTEL_PROPAGATORS | string | `"tracecontext,baggage,b3"` | | | component.backend.env.OTEL_VERSION | string | `"2.8.0"` | | | component.backend.env.REDIS_URL | string | `"redis://:wFSuJX9nDBdCa25sKZG7bh@opik-redis-master:6379/"` | | | component.backend.env.STATE_DB_DATABASE_NAME | string | `"opik"` | | From c730cd80511b9d960bd32db41f4b63c83f49121f Mon Sep 17 00:00:00 2001 From: Thiago Hora Date: Thu, 26 Sep 2024 14:56:55 +0200 Subject: [PATCH 06/10] Fix config --- .../main/java/com/comet/opik/domain/DatasetItemService.java | 6 ------ deployment/docker-compose/docker-compose.yaml | 6 +++++- deployment/helm_chart/opik/values.yaml | 1 + 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemService.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemService.java index 7d691b7cee..d69a09c566 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemService.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemService.java @@ -107,12 +107,6 @@ public Mono get(@NonNull UUID id) { return dao.get(id) .switchIfEmpty(Mono.defer(() -> Mono.error(failWithNotFound("Dataset item not found")))); } - - @Override - @WithSpan - public Flux getItems(@NonNull UUID datasetId, int limit, UUID lastRetrievedId) { - return dao.getItems(datasetId, limit, lastRetrievedId); - } @WithSpan public Flux getItems(@NonNull String workspaceId, @NonNull DatasetItemStreamRequest request) { diff --git a/deployment/docker-compose/docker-compose.yaml b/deployment/docker-compose/docker-compose.yaml index d11d003029..ea902128c5 100644 --- a/deployment/docker-compose/docker-compose.yaml +++ b/deployment/docker-compose/docker-compose.yaml @@ -83,10 +83,14 @@ services: JAVA_OPTS: "-Dliquibase.propertySubstitutionEnabled=true" REDIS_URL: redis://:opik@redis:6379/ ANALYTICS_DB_PASS: opik - OTEL_RESOURCE_ATTRIBUTES: "service.name=opik-backend,service.version=$OPIK_VERSION" OTEL_TRACES_EXPORTER: otlp OPIK_OTEL_SDK_ENABLED: false OTEL_VERSION: 2.8.0 + OTEL_PROPAGATORS: "tracecontext,baggage,b3" + OTEL_EXPERIMENTAL_EXPORTER_OTLP_RETRY_ENABLED: true + OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION: BASE2_EXPONENTIAL_BUCKET_HISTOGRAM + OTEL_EXPERIMENTAL_RESOURCE_DISABLED_KEYS: process.command_args + OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE: delta ports: - "8080" - "3003" diff --git a/deployment/helm_chart/opik/values.yaml b/deployment/helm_chart/opik/values.yaml index 8b741a659a..6fded6df5f 100644 --- a/deployment/helm_chart/opik/values.yaml +++ b/deployment/helm_chart/opik/values.yaml @@ -56,6 +56,7 @@ component: ANALYTICS_DB_MIGRATIONS_PASS: opik ANALYTICS_DB_PASS: opik STATE_DB_PASS: opik + OTEL_TRACES_EXPORTER: otlp OPIK_OTEL_SDK_ENABLED: false OTEL_VERSION: 2.8.0 OTEL_PROPAGATORS: "tracecontext,baggage,b3" From ef86a935169de06c4a4803a89108d376a09d47e7 Mon Sep 17 00:00:00 2001 From: CometActions Date: Thu, 26 Sep 2024 12:57:14 +0000 Subject: [PATCH 07/10] Update Helm documentation --- deployment/helm_chart/opik/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/deployment/helm_chart/opik/README.md b/deployment/helm_chart/opik/README.md index dde8d09a49..2f6cf6b4fa 100644 --- a/deployment/helm_chart/opik/README.md +++ b/deployment/helm_chart/opik/README.md @@ -115,6 +115,7 @@ Call opik api on http://localhost:5173/api | component.backend.env.OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION | string | `"BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"` | | | component.backend.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | string | `"delta"` | | | component.backend.env.OTEL_PROPAGATORS | string | `"tracecontext,baggage,b3"` | | +| component.backend.env.OTEL_TRACES_EXPORTER | string | `"otlp"` | | | component.backend.env.OTEL_VERSION | string | `"2.8.0"` | | | component.backend.env.REDIS_URL | string | `"redis://:wFSuJX9nDBdCa25sKZG7bh@opik-redis-master:6379/"` | | | component.backend.env.STATE_DB_DATABASE_NAME | string | `"opik"` | | From a0618b892cc13515a236e5878743c7c15ae6dcc0 Mon Sep 17 00:00:00 2001 From: Thiago Hora Date: Fri, 11 Oct 2024 18:11:21 +0200 Subject: [PATCH 08/10] Fix default --- deployment/docker-compose/docker-compose.yaml | 1 - deployment/helm_chart/opik/values.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/deployment/docker-compose/docker-compose.yaml b/deployment/docker-compose/docker-compose.yaml index 8011783146..cd5da6f4b1 100644 --- a/deployment/docker-compose/docker-compose.yaml +++ b/deployment/docker-compose/docker-compose.yaml @@ -85,7 +85,6 @@ services: JAVA_OPTS: "-Dliquibase.propertySubstitutionEnabled=true" REDIS_URL: redis://:opik@redis:6379/ ANALYTICS_DB_PASS: opik - OTEL_TRACES_EXPORTER: otlp OPIK_OTEL_SDK_ENABLED: false OTEL_VERSION: 2.8.0 OTEL_PROPAGATORS: "tracecontext,baggage,b3" diff --git a/deployment/helm_chart/opik/values.yaml b/deployment/helm_chart/opik/values.yaml index 6fded6df5f..8b741a659a 100644 --- a/deployment/helm_chart/opik/values.yaml +++ b/deployment/helm_chart/opik/values.yaml @@ -56,7 +56,6 @@ component: ANALYTICS_DB_MIGRATIONS_PASS: opik ANALYTICS_DB_PASS: opik STATE_DB_PASS: opik - OTEL_TRACES_EXPORTER: otlp OPIK_OTEL_SDK_ENABLED: false OTEL_VERSION: 2.8.0 OTEL_PROPAGATORS: "tracecontext,baggage,b3" From c6599b307d32c083b72131c53b09bf8ec58b4fbf Mon Sep 17 00:00:00 2001 From: CometActions Date: Fri, 11 Oct 2024 16:15:05 +0000 Subject: [PATCH 09/10] Update Helm documentation --- deployment/helm_chart/opik/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/deployment/helm_chart/opik/README.md b/deployment/helm_chart/opik/README.md index 2f6cf6b4fa..dde8d09a49 100644 --- a/deployment/helm_chart/opik/README.md +++ b/deployment/helm_chart/opik/README.md @@ -115,7 +115,6 @@ Call opik api on http://localhost:5173/api | component.backend.env.OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION | string | `"BASE2_EXPONENTIAL_BUCKET_HISTOGRAM"` | | | component.backend.env.OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | string | `"delta"` | | | component.backend.env.OTEL_PROPAGATORS | string | `"tracecontext,baggage,b3"` | | -| component.backend.env.OTEL_TRACES_EXPORTER | string | `"otlp"` | | | component.backend.env.OTEL_VERSION | string | `"2.8.0"` | | | component.backend.env.REDIS_URL | string | `"redis://:wFSuJX9nDBdCa25sKZG7bh@opik-redis-master:6379/"` | | | component.backend.env.STATE_DB_DATABASE_NAME | string | `"opik"` | | From 120cbd7d59ff395dadc43ab322fd2d81c89723a0 Mon Sep 17 00:00:00 2001 From: Thiago Hora Date: Fri, 11 Oct 2024 18:24:15 +0200 Subject: [PATCH 10/10] Fix --- .../main/java/com/comet/opik/domain/DatasetItemDAO.java | 4 ++-- .../src/main/java/com/comet/opik/domain/ExperimentDAO.java | 7 +++++++ .../main/java/com/comet/opik/domain/ExperimentItemDAO.java | 6 ++++++ .../main/java/com/comet/opik/domain/FeedbackScoreDAO.java | 7 +++++++ .../src/main/java/com/comet/opik/domain/TraceService.java | 2 +- 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemDAO.java index 034057bcd6..20317ad3c2 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/DatasetItemDAO.java @@ -726,7 +726,7 @@ public Mono getItems( bindSearchCriteria(datasetItemSearchCriteria, statement); return makeFluxContextAware(bindWorkspaceIdToFlux(statement)) - .doFinally(signalType -> segmentCount.end()) + .doFinally(signalType -> endSegment(segmentCount)) .flatMap(result -> result.map((row, rowMetadata) -> row.get(0, Long.class))) .reduce(0L, Long::sum) .flatMap(count -> { @@ -745,7 +745,7 @@ public Mono getItems( bindSearchCriteria(datasetItemSearchCriteria, selectStatement); return makeFluxContextAware(bindWorkspaceIdToFlux(selectStatement)) - .doFinally(signalType -> segment.end()) + .doFinally(signalType -> endSegment(segment)) .flatMap(this::mapItem) .collectList() .flatMap(items -> Mono.just(new DatasetItemPage(items, page, items.size(), count))); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/ExperimentDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/ExperimentDAO.java index 2e24de9ffe..4be64b5fdd 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/ExperimentDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/ExperimentDAO.java @@ -6,6 +6,7 @@ import com.comet.opik.utils.JsonUtils; import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.Preconditions; +import io.opentelemetry.instrumentation.annotations.WithSpan; import io.r2dbc.spi.Connection; import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.Result; @@ -372,6 +373,7 @@ AND ilike(name, CONCAT('%', :name, '%')) private final @NonNull ConnectionFactory connectionFactory; + @WithSpan Mono insert(@NonNull Experiment experiment) { return Mono.from(connectionFactory.create()) .flatMapMany(connection -> insert(experiment, connection)) @@ -398,6 +400,7 @@ private String getOrDefault(JsonNode jsonNode) { return Optional.ofNullable(jsonNode).map(JsonNode::toString).orElse(""); } + @WithSpan Mono getById(@NonNull UUID id) { return Mono.from(connectionFactory.create()) .flatMapMany(connection -> getById(id, connection)) @@ -447,6 +450,7 @@ private static List getFeedbackScores(Row row) { return feedbackScoresAvg.isEmpty() ? null : feedbackScoresAvg; } + @WithSpan Mono find( int page, int size, @NonNull ExperimentSearchCriteria experimentSearchCriteria) { return countTotal(experimentSearchCriteria).flatMap(total -> find(page, size, experimentSearchCriteria, total)); @@ -507,6 +511,7 @@ private void bindSearchCriteria(Statement statement, ExperimentSearchCriteria cr } } + @WithSpan Flux findByName(String name) { Preconditions.checkArgument(StringUtils.isNotBlank(name), "Argument 'name' must not be blank"); return Mono.from(connectionFactory.create()) @@ -520,6 +525,7 @@ private Publisher findByName(String name, Connection connectio return makeFluxContextAware(bindWorkspaceIdToFlux(statement)); } + @WithSpan public Flux getExperimentWorkspaces(@NonNull Set experimentIds) { if (experimentIds.isEmpty()) { return Flux.empty(); @@ -535,6 +541,7 @@ public Flux getExperimentWorkspaces(@NonNull Set e row.get("id", UUID.class)))); } + @WithSpan public Mono delete(Set ids) { Preconditions.checkArgument(CollectionUtils.isNotEmpty(ids), "Argument 'ids' must not be empty"); diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/ExperimentItemDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/ExperimentItemDAO.java index 2bf9d394d8..b456640e2a 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/ExperimentItemDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/ExperimentItemDAO.java @@ -2,6 +2,7 @@ import com.comet.opik.api.ExperimentItem; import com.google.common.base.Preconditions; +import io.opentelemetry.instrumentation.annotations.WithSpan; import io.r2dbc.spi.Connection; import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.Result; @@ -128,6 +129,7 @@ INSERT INTO experiment_items ( private final @NonNull ConnectionFactory connectionFactory; + @WithSpan public Flux findExperimentSummaryByDatasetIds(Collection datasetIds) { if (datasetIds.isEmpty()) { @@ -148,6 +150,7 @@ public Flux findExperimentSummaryByDatasetIds(Collection insert(@NonNull Set experimentItems) { Preconditions.checkArgument(CollectionUtils.isNotEmpty(experimentItems), "Argument 'experimentItems' must not be empty"); @@ -207,6 +210,7 @@ private Publisher mapToExperimentItem(Result result) { .build()); } + @WithSpan public Mono get(@NonNull UUID id) { return Mono.from(connectionFactory.create()) .flatMapMany(connection -> get(id, connection)) @@ -251,6 +255,7 @@ private Publisher getItems( return makeFluxContextAware(bindWorkspaceIdToFlux(statement)); } + @WithSpan public Mono delete(Set ids) { Preconditions.checkArgument(CollectionUtils.isNotEmpty(ids), "Argument 'ids' must not be empty"); @@ -270,6 +275,7 @@ private Publisher delete(Set ids, Connection connection) return makeFluxContextAware(bindWorkspaceIdToFlux(statement)); } + @WithSpan public Mono deleteByExperimentIds(Set experimentIds) { Preconditions.checkArgument(CollectionUtils.isNotEmpty(experimentIds), diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/FeedbackScoreDAO.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/FeedbackScoreDAO.java index e63db2530f..44b605fbf1 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/FeedbackScoreDAO.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/FeedbackScoreDAO.java @@ -5,6 +5,7 @@ import com.comet.opik.api.ScoreSource; import com.google.common.base.Preconditions; import com.google.inject.ImplementedBy; +import io.opentelemetry.instrumentation.annotations.WithSpan; import io.r2dbc.spi.Connection; import io.r2dbc.spi.Result; import io.r2dbc.spi.Row; @@ -256,6 +257,7 @@ AND entity_id IN ( """; @Override + @WithSpan public Mono>> getScores(@NonNull EntityType entityType, @NonNull List entityIds, @NonNull Connection connection) { @@ -309,6 +311,7 @@ private FeedbackScoreDto mapFeedback(Row row) { } @Override + @WithSpan public Mono scoreEntity(@NonNull EntityType entityType, @NonNull UUID entityId, @NonNull FeedbackScore score, @@ -343,6 +346,7 @@ public Mono scoreEntity(@NonNull EntityType entityType, } @Override + @WithSpan public Mono scoreBatchOf(@NonNull EntityType entityType, @NonNull List scores, @NonNull Connection connection) { @@ -401,6 +405,7 @@ public Mono scoreBatchOf(@NonNull EntityType entityType, } @Override + @WithSpan public Mono deleteScoreFrom(EntityType entityType, UUID id, String name, Connection connection) { var statement = connection.createStatement(DELETE_FEEDBACK_SCORE); @@ -415,12 +420,14 @@ public Mono deleteScoreFrom(EntityType entityType, UUID id, String name, C } @Override + @WithSpan public Mono deleteByEntityId( @NonNull EntityType entityType, @NonNull UUID entityId, @NonNull Connection connection) { return deleteByEntityIds(entityType, Set.of(entityId), connection); } @Override + @WithSpan public Mono deleteByEntityIds( @NonNull EntityType entityType, Set entityIds, @NonNull Connection connection) { Preconditions.checkArgument( diff --git a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java index db232a1b2d..404cf249eb 100644 --- a/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java +++ b/apps/opik-backend/src/main/java/com/comet/opik/domain/TraceService.java @@ -325,7 +325,7 @@ public Mono validateTraceWorkspace(@NonNull String workspaceId, @NonNul } @Override - @com.newrelic.api.agent.Trace(dispatcher = true) + @WithSpan public Mono countTracesPerWorkspace() { return template.stream(dao::countTracesPerWorkspace) .collectList()