ENH: Add ProfileLocation - Part 2 - performance metrics for transactions with label and profileLocation

This commit is contained in:
Rob Bygrave committed 2018-01-22 14:54:27 +13:00
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);
}
}
}
@@ -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);
@@ -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;
}
}