mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 14:40:46 +00:00
ENH: Add ProfileLocation - Part 2 - performance metrics for transactions with label and profileLocation
This commit is contained in:
1 parent
4e33027fdf
commit
51d2e4c600
37 files changed
+779
-33
No files matched your search
@@ -41,6 +41,8 @@ class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEventCode
|
||||
|
||||
private static final String notExpectedMessage = "Not expected on read only transaction";
|
||||
|
||||
private final TransactionManager manager;
|
||||
|
||||
/**
|
||||
* The status of the transaction.
|
||||
*/
|
||||
@@ -61,23 +63,37 @@ class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEventCode
|
||||
|
||||
private Map<String, Object> userObjects;
|
||||
|
||||
private long startNanos;
|
||||
|
||||
/**
|
||||
* Create without a tenantId.
|
||||
*/
|
||||
ImplicitReadOnlyTransaction(Connection connection) {
|
||||
ImplicitReadOnlyTransaction(TransactionManager manager, Connection connection) {
|
||||
this.manager = manager;
|
||||
this.active = true;
|
||||
this.connection = connection;
|
||||
this.persistenceContext = new DefaultPersistenceContext();
|
||||
this.startNanos = System.nanoTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create with a tenantId.
|
||||
*/
|
||||
ImplicitReadOnlyTransaction(Connection connection, Object tenantId) {
|
||||
this(connection);
|
||||
ImplicitReadOnlyTransaction(TransactionManager manager, Connection connection, Object tenantId) {
|
||||
this(manager, connection);
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLabel(String label) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long profileOffset() {
|
||||
return 0;
|
||||
@@ -475,6 +491,8 @@ class ImplicitReadOnlyTransaction implements SpiTransaction, TxnProfileEventCode
|
||||
}
|
||||
connection = null;
|
||||
active = false;
|
||||
long exeMicros = (System.nanoTime() - startNanos) / 1000L;
|
||||
manager.collectMetricReadOnly(exeMicros);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,6 +55,11 @@ public class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
*/
|
||||
protected final String id;
|
||||
|
||||
/**
|
||||
* The user defined label to group execution statistics.
|
||||
*/
|
||||
protected String label;
|
||||
|
||||
/**
|
||||
* Flag to indicate if this was an explicitly created Transaction.
|
||||
*/
|
||||
@@ -176,6 +181,8 @@ public class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
|
||||
protected ProfileLocation profileLocation;
|
||||
|
||||
protected final long startNanos;
|
||||
|
||||
/**
|
||||
* Create without ProfileStream option (no profiling).
|
||||
*/
|
||||
@@ -196,6 +203,7 @@ public class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
this.manager = manager;
|
||||
this.connection = connection;
|
||||
this.persistenceContext = new DefaultPersistenceContext();
|
||||
this.startNanos = System.nanoTime();
|
||||
|
||||
if (manager == null) {
|
||||
this.skipCacheAfterWrite = true;
|
||||
@@ -216,6 +224,16 @@ public class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLabel(String label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long profileOffset() {
|
||||
return (profileStream == null) ? 0 : profileStream.offset();
|
||||
@@ -980,8 +998,17 @@ public class JdbcTransaction implements SpiTransaction, TxnProfileEventCodes {
|
||||
}
|
||||
|
||||
private void profileEnd() {
|
||||
if (profileStream != null) {
|
||||
profileStream.end(manager);
|
||||
if (manager != null) {
|
||||
long exeMicros = (System.nanoTime() - startNanos) / 1000L;
|
||||
if (profileLocation != null) {
|
||||
profileLocation.add(exeMicros);
|
||||
} else if (label != null) {
|
||||
manager.collectMetricNamed(exeMicros, label);
|
||||
}
|
||||
manager.collectMetric(exeMicros);
|
||||
if (profileStream != null) {
|
||||
profileStream.end(manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ class TransactionFactoryBasicWithRead extends TransactionFactoryBasic {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = readOnlyDataSource.getConnection();
|
||||
return new ImplicitReadOnlyTransaction(connection);
|
||||
return new ImplicitReadOnlyTransaction(manager, connection);
|
||||
|
||||
} catch (PersistenceException ex) {
|
||||
JdbcClose.close(connection);
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ class TransactionFactoryTenantWithRead extends TransactionFactoryTenant {
|
||||
tenantId = tenantProvider.currentId();
|
||||
}
|
||||
connection = dataSourceSupplier.getReadOnlyConnection(tenantId);
|
||||
return new ImplicitReadOnlyTransaction(connection, tenantId);
|
||||
return new ImplicitReadOnlyTransaction(manager, connection, tenantId);
|
||||
|
||||
} catch (PersistenceException ex) {
|
||||
JdbcClose.close(connection);
|
||||
|
||||
@@ -8,13 +8,19 @@ import io.ebean.config.dbplatform.DatabasePlatform.OnQueryOnly;
|
||||
import io.ebean.event.changelog.ChangeLogListener;
|
||||
import io.ebean.event.changelog.ChangeLogPrepare;
|
||||
import io.ebean.event.changelog.ChangeSet;
|
||||
import io.ebean.meta.MetaTimedMetric;
|
||||
import io.ebeaninternal.api.SpiProfileHandler;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.api.TransactionEvent;
|
||||
import io.ebeaninternal.api.TransactionEventTable;
|
||||
import io.ebeaninternal.api.TransactionEventTable.TableIUD;
|
||||
import io.ebeaninternal.metric.MetricFactory;
|
||||
import io.ebeaninternal.metric.TimedMetric;
|
||||
import io.ebeaninternal.metric.TimedMetricMap;
|
||||
import io.ebeaninternal.server.cluster.ClusterManager;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptorManager;
|
||||
import io.ebeaninternal.server.profile.TimedProfileLocation;
|
||||
import io.ebeaninternal.server.profile.TimedProfileLocationRegistry;
|
||||
import io.ebeanservice.docstore.api.DocStoreTransaction;
|
||||
import io.ebeanservice.docstore.api.DocStoreUpdateProcessor;
|
||||
import io.ebeanservice.docstore.api.DocStoreUpdates;
|
||||
@@ -25,6 +31,7 @@ import javax.persistence.PersistenceException;
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -113,6 +120,11 @@ public class TransactionManager {
|
||||
|
||||
private final SpiProfileHandler profileHandler;
|
||||
|
||||
private final MetricFactory metricFactory;
|
||||
private final TimedMetric txnMain;
|
||||
private final TimedMetric txnReadOnly;
|
||||
private final TimedMetricMap txnNamed;
|
||||
|
||||
/**
|
||||
* Create the TransactionManager
|
||||
*/
|
||||
@@ -142,6 +154,10 @@ public class TransactionManager {
|
||||
|
||||
CurrentTenantProvider tenantProvider = options.config.getCurrentTenantProvider();
|
||||
this.transactionFactory = TransactionFactoryBuilder.build(this, dataSourceSupplier, tenantProvider);
|
||||
this.metricFactory = MetricFactory.get();
|
||||
this.txnMain = metricFactory.createTimedMetric("txn.main");
|
||||
this.txnReadOnly = metricFactory.createTimedMetric("txn.readonly");
|
||||
this.txnNamed = metricFactory.createTimedMetricMap("txn.named.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,7 +282,7 @@ public class TransactionManager {
|
||||
protected SpiTransaction createTransaction(int profileId, boolean explicit, Connection c, long id) {
|
||||
|
||||
ProfileStream profileStream = profileHandler.createProfileStream(profileId);
|
||||
return new JdbcTransaction(profileStream,prefix + id, explicit, c, this);
|
||||
return new JdbcTransaction(profileStream, prefix + id, explicit, c, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,4 +440,42 @@ public class TransactionManager {
|
||||
public void profileCollect(TransactionProfile transactionProfile) {
|
||||
profileHandler.collectTransactionProfile(transactionProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect execution time for an explicit transaction.
|
||||
*/
|
||||
public void collectMetric(long exeMicros) {
|
||||
txnMain.add(exeMicros);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect execution time for implicit read only transaction.
|
||||
*/
|
||||
public void collectMetricReadOnly(long exeMicros) {
|
||||
txnReadOnly.add(exeMicros);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect execution time for a named transaction.
|
||||
*/
|
||||
public void collectMetricNamed(long exeMicros, String label) {
|
||||
txnNamed.add(label, exeMicros);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect the transaction execution statistics since the last reset.
|
||||
*/
|
||||
public List<MetaTimedMetric> collectTransactionStatistics(boolean reset) {
|
||||
|
||||
List<MetaTimedMetric> list = new ArrayList<>();
|
||||
|
||||
txnMain.collect(reset, list);
|
||||
txnReadOnly.collect(reset, list);
|
||||
for (TimedProfileLocation timedLocation : TimedProfileLocationRegistry.registered()) {
|
||||
timedLocation.collect(reset, list);
|
||||
}
|
||||
txnNamed.collect(reset, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user