Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.ebean.ProfileLocation;
import io.ebeaninternal.server.transaction.ProfileStream;
import io.ebeaninternal.server.transaction.TransactionProfile;
import org.jspecify.annotations.Nullable;

/**
* Handle the logging or processing of transaction profiling information that is collected.
Expand All @@ -22,10 +23,13 @@ public interface SpiProfileHandler {
void collectTransactionProfile(TransactionProfile transactionProfile);

/**
* Create a profiling stream if we are profiling this transaction.
* Return null if we are not profiling this transaction.
* Create a profiling stream for this transaction, or return null to not profile this transaction.
* <p>
* The location is null for implicit read-only transactions (queries without an explicit transaction).
* Handlers should return null when they choose not to profile a given transaction.
* </p>
*
* @param location The profile location
* @param location The profile location, or null for implicit transactions
*/
ProfileStream createProfileStream(ProfileLocation location);
@Nullable ProfileStream createProfileStream(@Nullable ProfileLocation location);
}
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,11 @@ public CQuery(OrmQueryRequest<T> request, CQueryPredicates predicates, CQueryPla
this.autoTuneProfiling = profilingListener != null;
// set the generated sql back to the query
// so its available to the user...
query.setGeneratedSql(queryPlan.sql());
SqlTreePlan sqlTree = queryPlan.sqlTree();
this.rootNode = sqlTree.rootNode();
this.manyProperty = sqlTree.manyProperty();
this.sql = queryPlan.sql();
query.setGeneratedSql(sql);
this.rawSql = queryPlan.isRawSql();
this.logWhereSql = queryPlan.logWhereSql();
this.desc = request.descriptor();
Expand Down Expand Up @@ -567,7 +567,7 @@ private void updateStatistics() {
public void profile() {
transaction()
.profileStream()
.addQueryEvent(query.profileEventId(), profileOffset, desc.name(), loadedBeanCount, query.profileId());
.addQueryEvent(query.profileEventId(), profileOffset, desc.name(), loadedBeanCount, query.profileId(), query.getGeneratedSql());
}

QueryIterator<T> readIterate(int bufferSize, OrmQueryRequest<T> request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private void close() {
public void profile() {
transaction()
.profileStream()
.addQueryEvent(query.profileEventId(), profileOffset, desc.name(), rowCount, query.profileId());
.addQueryEvent(query.profileEventId(), profileOffset, desc.name(), rowCount, query.profileId(), query.getGeneratedSql());
}

Set<String> dependentTables() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private void close() {
public void profile() {
transaction()
.profileStream()
.addQueryEvent(query.profileEventId(), profileOffset, desc.name(), rowCount, query.profileId());
.addQueryEvent(query.profileEventId(), profileOffset, desc.name(), rowCount, query.profileId(), query.getGeneratedSql());
}

Set<String> dependentTables() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private void close() {
public void profile() {
transaction()
.profileStream()
.addQueryEvent(query.profileEventId(), profileOffset, desc.name(), rowCount, query.profileId());
.addQueryEvent(query.profileEventId(), profileOffset, desc.name(), rowCount, query.profileId(), query.getGeneratedSql());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.ebean.util.IOUtils;
import io.ebeaninternal.api.CoreLog;
import io.ebeaninternal.api.SpiProfileHandler;
import org.jspecify.annotations.Nullable;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -94,10 +95,14 @@ public void collectTransactionProfile(TransactionProfile transactionProfile) {
}

/**
* Create and return a ProfileStream.
* Create and return a ProfileStream, or null if location is null (implicit transactions
* are not profiled by the default file-based handler).
*/
@Override
public ProfileStream createProfileStream(ProfileLocation location) {
public ProfileStream createProfileStream(@Nullable ProfileLocation location) {
if (location == null) {
return null;
}
return new DefaultProfileStream(location, verbose);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.ebeaninternal.server.transaction;

import io.ebean.ProfileLocation;
import org.jspecify.annotations.Nullable;

/**
* Default transaction profiling event collection.
Expand All @@ -12,7 +13,7 @@ public final class DefaultProfileStream implements ProfileStream {
private final TransactionProfile profile;
private final TransactionProfile.Summary summary;

DefaultProfileStream(ProfileLocation location, boolean verbose) {
DefaultProfileStream(@Nullable ProfileLocation location, boolean verbose) {
this.startNanos = System.nanoTime();
this.profile = new TransactionProfile(System.currentTimeMillis(), location);
this.summary = profile.getSummary();
Expand All @@ -35,7 +36,7 @@ private long exeMicros(long offset) {
* Add a query execution event.
*/
@Override
public void addQueryEvent(String event, long offset, String beanName, int beanCount, String queryId) {
public void addQueryEvent(String event, long offset, String beanName, int beanCount, String queryId, String sql) {
long micros = exeMicros(offset);
summary.addQuery(micros, beanCount);
if (buffer != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ final class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEve
private final SpiTxnLogger logger;
private final boolean logSql;
private final boolean logSummary;
private ProfileStream profileStream;

/**
* The status of the transaction.
Expand Down Expand Up @@ -117,22 +118,24 @@ public String label() {

@Override
public long profileOffset() {
return 0;
return (profileStream == null) ? 0 : profileStream.offset();
}

@Override
public void profileEvent(SpiProfileTransactionEvent event) {
// do nothing
if (profileStream != null) {
event.profile();
}
}

@Override
public void setProfileStream(ProfileStream profileStream) {
// do nothing
this.profileStream = profileStream;
}

@Override
public ProfileStream profileStream() {
return null;
return profileStream;
}

@Override
Expand Down Expand Up @@ -497,6 +500,9 @@ private void deactivate() {
connection = null;
active = false;
manager.collectMetricReadOnly((System.nanoTime() - startNanos) / 1000L);
if (profileStream != null) {
profileStream.end(manager);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.ebean.ProfileLocation;
import io.ebeaninternal.api.SpiProfileHandler;
import org.jspecify.annotations.Nullable;

/**
* A do nothing SpiProfileHandler.
Expand All @@ -14,7 +15,7 @@ public void collectTransactionProfile(TransactionProfile transactionProfile) {
}

@Override
public ProfileStream createProfileStream(ProfileLocation location) {
public ProfileStream createProfileStream(@Nullable ProfileLocation location) {
// always return null
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public interface ProfileStream {
/**
* Add a query event.
*/
void addQueryEvent(String event, long offset, String beanName, int beanCount, String queryId);
void addQueryEvent(String event, long offset, String beanName, int beanCount, String queryId, String sql);

/**
* Add a persist event.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,12 @@ public SpiTransaction createTransaction(boolean explicit, int isolationLevel) {
* Create a new Transaction for query only purposes (can use read only datasource).
*/
public SpiTransaction createReadOnlyTransaction(Object tenantId, boolean useMaster) {
return transactionFactory.createReadOnlyTransaction(tenantId, useMaster);
SpiTransaction t = transactionFactory.createReadOnlyTransaction(tenantId, useMaster);
ProfileStream stream = profileHandler.createProfileStream(null);
if (stream != null) {
t.setProfileStream(stream);
}
return t;
}

/**
Expand Down Expand Up @@ -464,6 +469,10 @@ public final void clearServerTransaction() {
*/
public final SpiTransaction beginServerTransaction() {
SpiTransaction t = createTransaction(false, -1);
ProfileStream stream = profileHandler.createProfileStream(null);
if (stream != null) {
t.setProfileStream(stream);
}
scopeManager.set(t);
return t;
}
Expand Down Expand Up @@ -569,9 +578,10 @@ private void initNewTransaction(SpiTransaction transaction, TxScope txScope) {
registerProfileLocation(profileLocation);
}
transaction.setProfileLocation(profileLocation);
if (profileLocation.trace()) {
transaction.setProfileStream(profileHandler.createProfileStream(profileLocation));
}
}
ProfileStream stream = profileHandler.createProfileStream(profileLocation);
if (stream != null) {
transaction.setProfileStream(stream);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public final class TransactionProfile {
*/
public TransactionProfile(long startTime, ProfileLocation location) {
this.location = location;
this.label = location.label();
this.label = (location != null) ? location.label() : null;
this.startTime = startTime;
this.summary = new Summary();
}
Expand Down
5 changes: 3 additions & 2 deletions ebean-core/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
uses io.ebeaninternal.api.SpiDdlGeneratorProvider;
uses io.ebeaninternal.xmapping.api.XmapService;
uses io.ebeaninternal.server.autotune.AutoTuneServiceProvider;
uses io.ebeaninternal.api.SpiProfileHandler;
uses io.ebeaninternal.server.cluster.ClusterBroadcastFactory;

requires transitive io.ebean.api;
Expand Down Expand Up @@ -48,7 +49,7 @@
exports io.ebeanservice.docstore.api.support to io.ebean.elastic, io.ebean.test;
exports io.ebeanservice.docstore.api.mapping to io.ebean.elastic;

exports io.ebeaninternal.api to io.ebean.ddl.generator, io.ebean.querybean, io.ebean.autotune, io.ebean.postgis, io.ebean.test, io.ebean.elastic, io.ebean.spring.txn, io.ebean.postgis.types;
exports io.ebeaninternal.api to io.ebean.ddl.generator, io.ebean.querybean, io.ebean.autotune, io.ebean.postgis, io.ebean.test, io.ebean.elastic, io.ebean.spring.txn, io.ebean.postgis.types, io.ebean.opentelemetry;
exports io.ebeaninternal.api.json to io.ebean.test;
exports io.ebeaninternal.server.autotune to io.ebean.autotune;
exports io.ebeaninternal.server.core to io.ebean.test, io.ebean.elastic;
Expand All @@ -70,7 +71,7 @@
exports io.ebeaninternal.server.rawsql to io.ebean.test;
exports io.ebeaninternal.server.json to io.ebean.test, io.ebean.elastic;
exports io.ebeaninternal.server.type to io.ebean.postgis, io.ebean.test, io.ebean.postgis.types, io.ebean.pgvector;
exports io.ebeaninternal.server.transaction to io.ebean.test, io.ebean.elastic, io.ebean.spring.txn, io.ebean.k8scache;
exports io.ebeaninternal.server.transaction to io.ebean.test, io.ebean.elastic, io.ebean.spring.txn, io.ebean.k8scache, io.ebean.opentelemetry;
exports io.ebeaninternal.server.util to io.ebean.querybean;

provides io.ebean.service.BootstrapService with
Expand Down
66 changes: 66 additions & 0 deletions ebean-opentelemetry/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ebean-parent</artifactId>
<groupId>io.ebean</groupId>
<version>16.5.0</version>
</parent>

<artifactId>ebean-opentelemetry</artifactId>
<name>ebean-opentelemetry</name>
<description>Ebean OpenTelemetry integration - transaction and query tracing via SpiProfileHandler</description>

<properties>
<opentelemetry.version>1.51.0</opentelemetry.version>
<surefire.useModulePath>false</surefire.useModulePath>
</properties>

<dependencies>

<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-jsr305-x</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-core</artifactId>
<version>16.5.0</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-context</artifactId>
<version>${opentelemetry.version}</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>${opentelemetry.version}</version>
<scope>provided</scope>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
<version>${opentelemetry.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.ebean</groupId>
<artifactId>ebean-test</artifactId>
<version>16.5.0</version>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Loading
Loading