minor refresh of the Statistics API

- added getStart() returning an Instance
- removed a left-over @MXBean annotation
- refreshed some Javadoc
- fixed some warnings
This commit is contained in:
Gavin King 2022-01-11 22:21:23 +01:00
parent fda6e96c5e
commit f7b4a94c45
9 changed files with 230 additions and 190 deletions

View File

@ -9,7 +9,7 @@ package org.hibernate.stat;
import java.io.Serializable; import java.io.Serializable;
/** /**
* Second level cache statistics of a specific region * Second-level cache statistics of a specific region.
* *
* @author Gavin King * @author Gavin King
*/ */
@ -43,7 +43,7 @@ public interface CacheRegionStatistics extends Serializable {
/** /**
* The number of elements currently in memory within the cache provider. * The number of elements currently in memory within the cache provider.
* * <p>
* This is an optional value contingent upon the underlying cache provider * This is an optional value contingent upon the underlying cache provider
* providing extended stats support via * providing extended stats support via
* {@link org.hibernate.cache.spi.ExtendedStatisticsSupport}. If the provider * {@link org.hibernate.cache.spi.ExtendedStatisticsSupport}. If the provider
@ -54,7 +54,7 @@ public interface CacheRegionStatistics extends Serializable {
/** /**
* The number of elements currently stored to disk within the cache provider. * The number of elements currently stored to disk within the cache provider.
* * <p>
* This is an optional value contingent upon the underlying cache provider * This is an optional value contingent upon the underlying cache provider
* providing extended stats support via * providing extended stats support via
* {@link org.hibernate.cache.spi.ExtendedStatisticsSupport}. If the provider * {@link org.hibernate.cache.spi.ExtendedStatisticsSupport}. If the provider
@ -65,7 +65,7 @@ public interface CacheRegionStatistics extends Serializable {
/** /**
* The size that the in-memory elements take up within the cache provider. * The size that the in-memory elements take up within the cache provider.
* * <p>
* This is an optional value contingent upon the underlying cache provider * This is an optional value contingent upon the underlying cache provider
* providing extended stats support via * providing extended stats support via
* {@link org.hibernate.cache.spi.ExtendedStatisticsSupport}. If the provider * {@link org.hibernate.cache.spi.ExtendedStatisticsSupport}. If the provider

View File

@ -9,7 +9,7 @@ package org.hibernate.stat;
import java.io.Serializable; import java.io.Serializable;
/** /**
* Collection related statistics * Collection-related statistics.
* *
* @author Gavin King * @author Gavin King
* @author Steve Ebersole * @author Steve Ebersole

View File

@ -9,7 +9,7 @@ package org.hibernate.stat;
import java.io.Serializable; import java.io.Serializable;
/** /**
* Entity related statistics * Entity-related statistics.
* *
* @author Gavin King * @author Gavin King
* @author Steve Ebersole * @author Steve Ebersole

View File

@ -9,12 +9,13 @@ package org.hibernate.stat;
import java.io.Serializable; import java.io.Serializable;
/** /**
* Statistics pertaining to the execution of the "natural id resolution" query. * Statistics pertaining to the execution of queries which resolve a natural
* id lookup against the database.
* *
* @apiNote The natural-id resolution data is allowed to be stored in the * @apiNote The natural-id resolution data is allowed to be stored in the
* second level cache, and if so stored will have available caching stats as * second-level cache, and if so stored will have available caching stats as
* well available via {@link Statistics#getDomainDataRegionStatistics} using the * well available via {@link Statistics#getDomainDataRegionStatistics} using
* configured region name * the configured region name
* *
* todo (6.0) : consider a means to get the cache Region statistics for: * todo (6.0) : consider a means to get the cache Region statistics for:
* 1) an entity by name * 1) an entity by name

View File

@ -9,9 +9,11 @@ package org.hibernate.stat;
import java.io.Serializable; import java.io.Serializable;
/** /**
* Query statistics (HQL and SQL) * Statistics relating to a particular query written in HQL or SQL.
* <p/> * <p>
* Note that for a cached query, the cache miss is equals to the db count * Note that for a cached query, the number of cache missed is the
* same as the number of queries actually executed against the
* database.
* *
* @author Gavin King * @author Gavin King
* @author Steve Ebersole * @author Steve Ebersole
@ -23,7 +25,8 @@ public interface QueryStatistics extends Serializable {
long getExecutionCount(); long getExecutionCount();
/** /**
* How many ResultSet rows have been processed for this query ? * How many {@link java.sql.ResultSet} rows have been processed
* for this query
*/ */
long getExecutionRowCount(); long getExecutionRowCount();
@ -43,7 +46,8 @@ public interface QueryStatistics extends Serializable {
long getExecutionMinTime(); long getExecutionMinTime();
/** /**
* How long, cumulatively, have all executions of this query taken? * How long, cumulatively, have all executions of this query
* taken?
*/ */
long getExecutionTotalTime(); long getExecutionTotalTime();
@ -77,7 +81,8 @@ public interface QueryStatistics extends Serializable {
long getCachePutCount(); long getCachePutCount();
/** /**
* The number of query plans successfully fetched from the cache. * The number of query plans successfully fetched from the
* cache.
*/ */
default long getPlanCacheHitCount() { default long getPlanCacheHitCount() {
//For backward compatibility //For backward compatibility
@ -93,7 +98,8 @@ public interface QueryStatistics extends Serializable {
} }
/** /**
* The overall time spent to compile the plan for this particular query. * The overall time spent to compile the plan for this
* particular query.
*/ */
default long getPlanCompilationTotalMicroseconds() { default long getPlanCompilationTotalMicroseconds() {
//For backward compatibility //For backward compatibility

View File

@ -9,28 +9,29 @@ package org.hibernate.stat;
import java.util.Set; import java.util.Set;
/** /**
* Information about the first-level (session) cache * Information about the first-level (session) cache for a particular
* for a particular session instance * instance of {@link org.hibernate.Session}.
*
* @author Gavin King * @author Gavin King
*/ */
public interface SessionStatistics { public interface SessionStatistics {
/** /**
* Get the number of entity instances associated with the session * The number of entity instances associated with the session.
*/ */
int getEntityCount(); int getEntityCount();
/** /**
* Get the number of collection instances associated with the session * The number of collection instances associated with the session.
*/ */
int getCollectionCount(); int getCollectionCount();
/** /**
* Get the set of all {@code EntityKey}s * The set of all {@link org.hibernate.engine.spi.EntityKey}s
* @see org.hibernate.engine.spi.EntityKey * currently held within the persistence context.
*/ */
Set<?> getEntityKeys(); Set<?> getEntityKeys();
/** /**
* Get the set of all {@code CollectionKey}s * The set of all {@link org.hibernate.engine.spi.CollectionKey}s
* @see org.hibernate.engine.spi.CollectionKey * currently held within the persistence context.
*/ */
Set<?> getCollectionKeys(); Set<?> getCollectionKeys();

View File

@ -6,373 +6,400 @@
*/ */
package org.hibernate.stat; package org.hibernate.stat;
import javax.management.MXBean; import java.time.Instant;
/** /**
* Exposes statistics for a particular {@link org.hibernate.SessionFactory}. Beware of milliseconds metrics, they * Exposes statistics collected from all sessions belonging to a
* are dependent of the JVM precision: you may then encounter a 10 ms approximation depending on you OS platform. * particular {@link org.hibernate.SessionFactory}.
* Please refer to the JVM documentation for more information. * <p>
* Collection of statistics is enabled if the configuration property
* {@link org.hibernate.cfg.AvailableSettings#GENERATE_STATISTICS} is
* set to {@code true}. It may be dynamically enabled or disabled at
* runtime by calling {@link #setStatisticsEnabled(boolean)}.
* *
* @author Emmanuel Bernard * @author Emmanuel Bernard
*/ */
@MXBean
public interface Statistics { public interface Statistics {
/**
* The default value of the configuration property
* {@link org.hibernate.cfg.AvailableSettings#QUERY_STATISTICS_MAX_SIZE}.
*/
int DEFAULT_QUERY_STATISTICS_MAX_SIZE = 5000; int DEFAULT_QUERY_STATISTICS_MAX_SIZE = 5000;
/** /**
* Are statistics enabled * Is collection of statistics enabled?
*/ */
boolean isStatisticsEnabled(); boolean isStatisticsEnabled();
/** /**
* Enable statistics logs (this is a dynamic parameter) * Enable or disable statistics collection.
*/ */
void setStatisticsEnabled(boolean b); void setStatisticsEnabled(boolean enabled);
/** /**
* reset all statistics * Reset all statistics.
*/ */
void clear(); void clear();
/** /**
* log in info level the main statistics * Log the main statistics at level {@code INFO}.
*/ */
void logSummary(); void logSummary();
/** /**
* find entity statistics per name * Obtain the statistics for the entity with the given name.
* *
* @param entityName entity name * @param entityName the entity name
* @return EntityStatistics object
*/ */
EntityStatistics getEntityStatistics(String entityName); EntityStatistics getEntityStatistics(String entityName);
/** /**
* Get collection statistics per role * Obtain the statistics for the collection with the given role.
* *
* @param role collection role * @param role the collection role
* @return CollectionStatistics
*/ */
CollectionStatistics getCollectionStatistics(String role); CollectionStatistics getCollectionStatistics(String role);
/** /**
* Natural id resolution query statistics for an entity type * Obtain the natural id resolution statistics for the entity
* type with the given name.
* *
* @param entityName The entity name that is the root of the hierarchy containing the * @param entityName The entity name that is the root of the
* natural id * hierarchy containing the natural id
* @return NaturalIdCacheStatistics
*/ */
NaturalIdStatistics getNaturalIdStatistics(String entityName); NaturalIdStatistics getNaturalIdStatistics(String entityName);
/** /**
* Query statistics from query string (HQL or SQL) * Obtain the query statistics for the given query string.
* *
* @param queryString query string * @param queryString the query string, written in HQL or SQL
* @return QueryStatistics
*/ */
QueryStatistics getQueryStatistics(String queryString); QueryStatistics getQueryStatistics(String queryString);
/** /**
* Second-level cache statistics per domain data (entity, collection, natural-id) region * Obtain the second-level cache statistics for the given cache
* region.
* *
* @param regionName The unqualified region name * @param regionName The unqualified region name
* *
* @return The stats for the named region, or {@code null} if the second level cache is * @return the statistics for the named region, or {@code null}
* not enabled * if the second-level cache is not enabled
* *
* @throws IllegalArgumentException if the region name could not be resolved * @throws IllegalArgumentException if there is no region with the given name
*/ */
CacheRegionStatistics getDomainDataRegionStatistics(String regionName); CacheRegionStatistics getDomainDataRegionStatistics(String regionName);
/** /**
* Second-level cache statistics per query region * Obtain the second-level cache statistics for the given query
* cache region.
* *
* @param regionName The unqualified region name * @param regionName The unqualified region name
* *
* @return Stats for the named region, or {@code null} if (1) query result caching is * @return the statistics for the named region, or {@code null}
* not enabled or (2) no query region exists with that name * if either query result caching is not enabled, or no
* query cache region exists with the given name
*/ */
CacheRegionStatistics getQueryRegionStatistics(String regionName); CacheRegionStatistics getQueryRegionStatistics(String regionName);
/** /**
* Get statistics for either a domain-data or query-result region - this * Obtain the statistics for either a domain data or query result
* method checks both, preferring domain data region if one. Think of it * cache region.
* as a cascading check to:<ol> * <p>
* This method checks both, preferring the domain data region if
* there is one. Think of it as a cascading check to:<ol>
* <li>{@link #getDomainDataRegionStatistics}</li> * <li>{@link #getDomainDataRegionStatistics}</li>
* <li>{@link #getQueryRegionStatistics}</li> * <li>{@link #getQueryRegionStatistics}</li>
* </ol> * </ol>
* Note that returning null is preferred here over throwing an exception when * Note that null is returned instead of throwing an exception when
* no region exists with that name. * no region exists with the given name.
* *
* @param regionName The unqualified region name * @param regionName The unqualified region name
* *
* @return Stats for the named region, or {@code null} if no such region exists * @return the statistics for the named region, or {@code null} if
* there is no region with the given name
*/ */
CacheRegionStatistics getCacheRegionStatistics(String regionName); CacheRegionStatistics getCacheRegionStatistics(String regionName);
/** /**
* Get global number of entity deletes * The global number of entity deletes.
* @return entity deletion count
*/ */
long getEntityDeleteCount(); long getEntityDeleteCount();
/** /**
* Get global number of entity inserts * The global number of entity inserts.
* @return entity insertion count
*/ */
long getEntityInsertCount(); long getEntityInsertCount();
/** /**
* Get global number of entity loads * The global number of entity loads.
* @return entity load (from DB)
*/ */
long getEntityLoadCount(); long getEntityLoadCount();
/** /**
* Get global number of entity fetches * The global number of entity fetches.
* @return entity fetch (from DB)
*/ */
long getEntityFetchCount(); long getEntityFetchCount();
/** /**
* Get global number of entity updates * The global number of entity updates.
* @return entity update
*/ */
long getEntityUpdateCount(); long getEntityUpdateCount();
/** /**
* Get global number of executed queries * The global number of executed queries.
* @return query execution count
*/ */
long getQueryExecutionCount(); long getQueryExecutionCount();
/** /**
* Get the time in milliseconds of the slowest query. * The time in milliseconds of the slowest query.
*/ */
long getQueryExecutionMaxTime(); long getQueryExecutionMaxTime();
/** /**
* Get the query string for the slowest query. * The query string for the slowest query.
*/ */
String getQueryExecutionMaxTimeQueryString(); String getQueryExecutionMaxTimeQueryString();
/** /**
* Get the global number of cached queries successfully retrieved from cache * The global number of cached queries successfully retrieved from
* the cache.
*/ */
long getQueryCacheHitCount(); long getQueryCacheHitCount();
/** /**
* Get the global number of cached queries *not* found in cache * The global number of cached queries <em>not</em>not found in the
* cache.
*/ */
long getQueryCacheMissCount(); long getQueryCacheMissCount();
/** /**
* Get the global number of cacheable queries put in cache * The global number of cacheable queries put in cache.
*/ */
long getQueryCachePutCount(); long getQueryCachePutCount();
/** /**
* Get the global number of natural id queries executed against the database * The global number of natural id queries executed against the
* database.
*/ */
long getNaturalIdQueryExecutionCount(); long getNaturalIdQueryExecutionCount();
/** /**
* Get the global maximum query time for natural id queries executed against the database * The global maximum query time for natural id queries executed
* against the database.
*/ */
long getNaturalIdQueryExecutionMaxTime(); long getNaturalIdQueryExecutionMaxTime();
/** /**
* Get the region for the maximum natural id query time * The region for the maximum natural id query time.
*/ */
String getNaturalIdQueryExecutionMaxTimeRegion(); String getNaturalIdQueryExecutionMaxTimeRegion();
/** /**
* Get the entity for the maximum natural id query time * The entity name for the maximum natural id query time.
*/ */
String getNaturalIdQueryExecutionMaxTimeEntity(); String getNaturalIdQueryExecutionMaxTimeEntity();
/** /**
* Get the global number of cached natural id lookups successfully retrieved from cache * The global number of cached natural id lookups successfully
* retrieved from the cache.
*/ */
long getNaturalIdCacheHitCount(); long getNaturalIdCacheHitCount();
/** /**
* Get the global number of cached natural id lookups *not* found in cache * The global number of cached natural id lookups <em>not</em> found
* in the cache.
*/ */
long getNaturalIdCacheMissCount(); long getNaturalIdCacheMissCount();
/** /**
* Get the global number of cacheable natural id lookups put in cache * The global number of cacheable natural id lookups put in cache.
*/ */
long getNaturalIdCachePutCount(); long getNaturalIdCachePutCount();
/** /**
* Get the global number of timestamps successfully retrieved from cache * The global number of timestamps successfully retrieved from cache.
*/ */
long getUpdateTimestampsCacheHitCount(); long getUpdateTimestampsCacheHitCount();
/** /**
* Get the global number of timestamp requests that were not found in the cache * The global number of timestamp requests that were not found in the
* cache.
*/ */
long getUpdateTimestampsCacheMissCount(); long getUpdateTimestampsCacheMissCount();
/** /**
* Get the global number of timestamps put in cache * The global number of timestamps put in cache.
*/ */
long getUpdateTimestampsCachePutCount(); long getUpdateTimestampsCachePutCount();
/** /**
* Get the global number of flush operations executed (either manual or automatic). * The global number of flush operations executed, including automatic
* (either manual or automatic).
*/ */
long getFlushCount(); long getFlushCount();
/** /**
* Get the global number of connections asked by the sessions * The global number of connections requested by sessions.
* (the actual number of connections used may be much smaller depending * <p>
* whether you use a connection pool or not) * The actual number of connections used may be much smaller, assuming
* that a connection pool is in use.
*/ */
long getConnectCount(); long getConnectCount();
/** /**
* Global number of cacheable entities/collections successfully retrieved from the cache * The global number of cacheable entities and collections successfully
* retrieved from the cache.
*/ */
long getSecondLevelCacheHitCount(); long getSecondLevelCacheHitCount();
/** /**
* Global number of cacheable entities/collections not found in the cache and loaded from the database. * The global number of cacheable entities collections not found in the
* cache and loaded from the database.
*/ */
long getSecondLevelCacheMissCount(); long getSecondLevelCacheMissCount();
/** /**
* Global number of cacheable entities/collections put in the cache * The global number of cacheable entities and collections put in the
* cache.
*/ */
long getSecondLevelCachePutCount(); long getSecondLevelCachePutCount();
/** /**
* Global number of sessions closed * The global number of sessions closed.
*/ */
long getSessionCloseCount(); long getSessionCloseCount();
/** /**
* Global number of sessions opened * The global number of sessions opened.
*/ */
long getSessionOpenCount(); long getSessionOpenCount();
/** /**
* Global number of collections loaded * The global number of collections loaded.
*/ */
long getCollectionLoadCount(); long getCollectionLoadCount();
/** /**
* Global number of collections fetched * The global number of collections fetched.
*/ */
long getCollectionFetchCount(); long getCollectionFetchCount();
/** /**
* Global number of collections updated * The global number of collections updated.
*/ */
long getCollectionUpdateCount(); long getCollectionUpdateCount();
/** /**
* Global number of collections removed * The global number of collections removed.
*/ */
//even on inverse="true" //even on inverse="true"
long getCollectionRemoveCount(); long getCollectionRemoveCount();
/** /**
* Global number of collections recreated * The global number of collections recreated
*/ */
long getCollectionRecreateCount(); long getCollectionRecreateCount();
/** /**
* The milliseconds (JVM standard {@link System#currentTimeMillis()}) * The {@link Instant} at which this instance of {@code Statistics}
* since the initial creation of this Statistics * was created, or since the last time {@link #clear()} was called.
* instance or the last time {@link #clear()} was called.
*
* @apiNote This time(stamp) is
*/ */
Instant getStart();
/**
* The {@linkplain Instant#toEpochMilli()} milliseconds}) since the
* initial creation of this instance, or since the last time
* {@link #clear()} was called.
*
* @deprecated use {@link #getStart()}
*/
@Deprecated(since = "6.0")
long getStartTime(); long getStartTime();
/** /**
* Get all executed query strings. * All executed query strings.
* * <p>
* The maximum number of queries tracked by the Hibernate statistics is given by the {@code hibernate.statistics.query_max_size} property. * The maximum number of queries tracked by the Hibernate statistics
* is determined by the configuration property
* {@link org.hibernate.cfg.AvailableSettings#QUERY_STATISTICS_MAX_SIZE}.
*/ */
String[] getQueries(); String[] getQueries();
/** /**
* Get the names of all entities * The names of all entities.
*/ */
String[] getEntityNames(); String[] getEntityNames();
/** /**
* Get the names of all collection roles * The names of all collection roles.
*/ */
String[] getCollectionRoleNames(); String[] getCollectionRoleNames();
/** /**
* Get all second-level cache region names. Note: for backwards * All second-level cache region names. For backwards compatibility,
* compatibility this method returns just the names of regions * this method returns just the names of regions storing domain data,
* storing domain data, not query result regions * not query result cache regions.
*/ */
String[] getSecondLevelCacheRegionNames(); String[] getSecondLevelCacheRegionNames();
/** /**
* The number of transactions we know to have been successful * The number of transactions we know to have been successful.
*/ */
long getSuccessfulTransactionCount(); long getSuccessfulTransactionCount();
/** /**
* The number of transactions we know to have completed * The number of transactions we know to have completed.
*/ */
long getTransactionCount(); long getTransactionCount();
/** /**
* The number of prepared statements that were acquired * The number of prepared statements that were acquired.
*/ */
long getPrepareStatementCount(); long getPrepareStatementCount();
/** /**
* The number of prepared statements that were released * The number of prepared statements that were released.
*/ */
long getCloseStatementCount(); long getCloseStatementCount();
/** /**
* The number of Hibernate {@code StaleObjectStateException}s or JPA {@code OptimisticLockException}s * The number of Hibernate {@code StaleObjectStateException}s or JPA
* that occurred. * {@code OptimisticLockException}s that have occurred.
*/ */
long getOptimisticFailureCount(); long getOptimisticFailureCount();
/** /**
* Second-level cache statistics per region * Second-level cache statistics per region.
* *
* @param regionName qualified region name * @param regionName qualified region name
* *
* @return SecondLevelCacheStatistics or {@code null} if the second level cache is not enabled * @return the statistics object, or {@code null} if the second-level
* cache is not enabled
* *
* @throws IllegalArgumentException if the region name could not be resolved * @throws IllegalArgumentException if there is no region with the given name
* *
* @deprecated (since 5.3) Use {@link #getDomainDataRegionStatistics} instead * @deprecated Use {@link #getDomainDataRegionStatistics}
*/ */
@Deprecated @Deprecated(since = "5.3")
SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName); SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName);
/** /**
* Natural id cache statistics per region * Natural id cache statistics per region.
* *
* @param regionName region name * @param regionName region name
* @return NaturalIdCacheStatistics * @return NaturalIdCacheStatistics
* *
* @deprecated (since 5.3) Use {@link #getNaturalIdStatistics} or * @deprecated Use {@link #getNaturalIdStatistics} or
* {@link #getDomainDataRegionStatistics} instead depending on need * {@link #getDomainDataRegionStatistics}
*/ */
@Deprecated @Deprecated(since = "5.3")
NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName); NaturalIdCacheStatistics getNaturalIdCacheStatistics(String regionName);
/** /**
* Get the global number of query plans successfully retrieved from cache * The global number of query plans successfully retrieved from cache.
*/ */
default long getQueryPlanCacheHitCount() { default long getQueryPlanCacheHitCount() {
//For backward compatibility //For backward compatibility
@ -380,7 +407,7 @@ public interface Statistics {
} }
/** /**
* Get the global number of query plans lookups *not* found in cache * The global number of query plans lookups <em>not</em> found in cache.
*/ */
default long getQueryPlanCacheMissCount() { default long getQueryPlanCacheMissCount() {
//For backward compatibility //For backward compatibility

View File

@ -6,6 +6,7 @@
*/ */
package org.hibernate.stat.internal; package org.hibernate.stat.internal;
import java.time.Instant;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder; import java.util.concurrent.atomic.LongAdder;
@ -32,7 +33,6 @@ import static org.hibernate.internal.CoreLogging.messageLogger;
* @author Alex Snaps * @author Alex Snaps
* @author Sanne Grinovero * @author Sanne Grinovero
*/ */
@SuppressWarnings({ "unchecked" })
public class StatisticsImpl implements StatisticsImplementor, Service { public class StatisticsImpl implements StatisticsImplementor, Service {
private static final CoreMessageLogger LOG = messageLogger( StatisticsImpl.class ); private static final CoreMessageLogger LOG = messageLogger( StatisticsImpl.class );
@ -44,7 +44,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
private final boolean queryCacheEnabled; private final boolean queryCacheEnabled;
private volatile boolean isStatisticsEnabled; private volatile boolean isStatisticsEnabled;
private volatile long startTime; private volatile Instant startTime;
private final LongAdder sessionOpenCount = new LongAdder(); private final LongAdder sessionOpenCount = new LongAdder();
private final LongAdder sessionCloseCount = new LongAdder(); private final LongAdder sessionCloseCount = new LongAdder();
@ -96,9 +96,9 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
private final LongAdder optimisticFailureCount = new LongAdder(); private final LongAdder optimisticFailureCount = new LongAdder();
private final StatsNamedContainer<EntityStatisticsImpl> entityStatsMap = new StatsNamedContainer(); private final StatsNamedContainer<EntityStatisticsImpl> entityStatsMap = new StatsNamedContainer<>();
private final StatsNamedContainer<NaturalIdStatisticsImpl> naturalIdQueryStatsMap = new StatsNamedContainer(); private final StatsNamedContainer<NaturalIdStatisticsImpl> naturalIdQueryStatsMap = new StatsNamedContainer<>();
private final StatsNamedContainer<CollectionStatisticsImpl> collectionStatsMap = new StatsNamedContainer(); private final StatsNamedContainer<CollectionStatisticsImpl> collectionStatsMap = new StatsNamedContainer<>();
/** /**
* Keyed by query string * Keyed by query string
@ -110,18 +110,19 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
*/ */
private final StatsNamedContainer<CacheRegionStatisticsImpl> l2CacheStatsMap = new StatsNamedContainer<>(); private final StatsNamedContainer<CacheRegionStatisticsImpl> l2CacheStatsMap = new StatsNamedContainer<>();
private final StatsNamedContainer<DeprecatedNaturalIdCacheStatisticsImpl> deprecatedNaturalIdStatsMap = new StatsNamedContainer(); private final StatsNamedContainer<DeprecatedNaturalIdCacheStatisticsImpl> deprecatedNaturalIdStatsMap
= new StatsNamedContainer<>();
public StatisticsImpl(SessionFactoryImplementor sessionFactory) { public StatisticsImpl(SessionFactoryImplementor sessionFactory) {
Objects.requireNonNull( sessionFactory ); Objects.requireNonNull( sessionFactory );
SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions(); SessionFactoryOptions sessionFactoryOptions = sessionFactory.getSessionFactoryOptions();
this.queryStatsMap = new StatsNamedContainer( this.queryStatsMap = new StatsNamedContainer<>(
sessionFactory != null ? sessionFactory != null ?
sessionFactoryOptions.getQueryStatisticsMaxSize() : sessionFactoryOptions.getQueryStatisticsMaxSize() :
Statistics.DEFAULT_QUERY_STATISTICS_MAX_SIZE, Statistics.DEFAULT_QUERY_STATISTICS_MAX_SIZE,
20 20
); );
resetStartTime(); resetStart();
metamodel = sessionFactory.getMetamodel(); metamodel = sessionFactory.getMetamodel();
cache = sessionFactory.getCache(); cache = sessionFactory.getCache();
cacheRegionPrefix = sessionFactoryOptions.getCacheRegionPrefix(); cacheRegionPrefix = sessionFactoryOptions.getCacheRegionPrefix();
@ -191,16 +192,21 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
queryPlanCacheHitCount.reset(); queryPlanCacheHitCount.reset();
queryPlanCacheMissCount.reset(); queryPlanCacheMissCount.reset();
resetStartTime(); resetStart();
} }
private void resetStartTime() { private void resetStart() {
startTime = System.currentTimeMillis(); startTime = Instant.now();
}
@Override
public Instant getStart() {
return startTime;
} }
@Override @Override
public long getStartTime() { public long getStartTime() {
return startTime; return startTime.toEpochMilli();
} }
@Override @Override
@ -209,8 +215,8 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
} }
@Override @Override
public void setStatisticsEnabled(boolean b) { public void setStatisticsEnabled(boolean enabled) {
isStatisticsEnabled = b; isStatisticsEnabled = enabled;
} }
@ -875,7 +881,7 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
@Override @Override
public void logSummary() { public void logSummary() {
LOG.loggingStatistics(); LOG.loggingStatistics();
LOG.startTime( startTime ); LOG.startTime( startTime.toEpochMilli() );
LOG.sessionsOpened( sessionOpenCount.sum() ); LOG.sessionsOpened( sessionOpenCount.sum() );
LOG.sessionsClosed( sessionCloseCount.sum() ); LOG.sessionsClosed( sessionCloseCount.sum() );
LOG.transactions( transactionCount.sum() ); LOG.transactions( transactionCount.sum() );
@ -917,48 +923,46 @@ public class StatisticsImpl implements StatisticsImplementor, Service {
@Override @Override
public String toString() { public String toString() {
return new StringBuilder() return "Statistics[" +
.append( "Statistics[" ) "start time=" + startTime +
.append( "start time=" ).append( startTime ) ",sessions opened=" + sessionOpenCount +
.append( ",sessions opened=" ).append( sessionOpenCount ) ",sessions closed=" + sessionCloseCount +
.append( ",sessions closed=" ).append( sessionCloseCount ) ",transactions=" + transactionCount +
.append( ",transactions=" ).append( transactionCount ) ",successful transactions=" + committedTransactionCount +
.append( ",successful transactions=" ).append( committedTransactionCount ) ",optimistic lock failures=" + optimisticFailureCount +
.append( ",optimistic lock failures=" ).append( optimisticFailureCount ) ",flushes=" + flushCount +
.append( ",flushes=" ).append( flushCount ) ",connections obtained=" + connectCount +
.append( ",connections obtained=" ).append( connectCount ) ",statements prepared=" + prepareStatementCount +
.append( ",statements prepared=" ).append( prepareStatementCount ) ",statements closed=" + closeStatementCount +
.append( ",statements closed=" ).append( closeStatementCount ) ",second level cache puts=" + secondLevelCachePutCount +
.append( ",second level cache puts=" ).append( secondLevelCachePutCount ) ",second level cache hits=" + secondLevelCacheHitCount +
.append( ",second level cache hits=" ).append( secondLevelCacheHitCount ) ",second level cache misses=" + secondLevelCacheMissCount +
.append( ",second level cache misses=" ).append( secondLevelCacheMissCount ) ",entities loaded=" + entityLoadCount +
.append( ",entities loaded=" ).append( entityLoadCount ) ",entities updated=" + entityUpdateCount +
.append( ",entities updated=" ).append( entityUpdateCount ) ",entities inserted=" + entityInsertCount +
.append( ",entities inserted=" ).append( entityInsertCount ) ",entities deleted=" + entityDeleteCount +
.append( ",entities deleted=" ).append( entityDeleteCount ) ",entities fetched=" + entityFetchCount +
.append( ",entities fetched=" ).append( entityFetchCount ) ",collections loaded=" + collectionLoadCount +
.append( ",collections loaded=" ).append( collectionLoadCount ) ",collections updated=" + collectionUpdateCount +
.append( ",collections updated=" ).append( collectionUpdateCount ) ",collections removed=" + collectionRemoveCount +
.append( ",collections removed=" ).append( collectionRemoveCount ) ",collections recreated=" + collectionRecreateCount +
.append( ",collections recreated=" ).append( collectionRecreateCount ) ",collections fetched=" + collectionFetchCount +
.append( ",collections fetched=" ).append( collectionFetchCount ) ",naturalId queries executed to database=" + naturalIdQueryExecutionCount +
.append( ",naturalId queries executed to database=" ).append( naturalIdQueryExecutionCount ) ",naturalId cache puts=" + naturalIdCachePutCount +
.append( ",naturalId cache puts=" ).append( naturalIdCachePutCount ) ",naturalId cache hits=" + naturalIdCacheHitCount +
.append( ",naturalId cache hits=" ).append( naturalIdCacheHitCount ) ",naturalId cache misses=" + naturalIdCacheMissCount +
.append( ",naturalId cache misses=" ).append( naturalIdCacheMissCount ) ",naturalId max query time=" + naturalIdQueryExecutionMaxTime +
.append( ",naturalId max query time=" ).append( naturalIdQueryExecutionMaxTime ) ",queries executed to database=" + queryExecutionCount +
.append( ",queries executed to database=" ).append( queryExecutionCount ) ",query cache puts=" + queryCachePutCount +
.append( ",query cache puts=" ).append( queryCachePutCount ) ",query cache hits=" + queryCacheHitCount +
.append( ",query cache hits=" ).append( queryCacheHitCount ) ",query cache misses=" + queryCacheMissCount +
.append( ",query cache misses=" ).append( queryCacheMissCount ) ",update timestamps cache puts=" + updateTimestampsCachePutCount +
.append(",update timestamps cache puts=").append(updateTimestampsCachePutCount) ",update timestamps cache hits=" + updateTimestampsCacheHitCount +
.append(",update timestamps cache hits=").append(updateTimestampsCacheHitCount) ",update timestamps cache misses=" + updateTimestampsCacheMissCount +
.append(",update timestamps cache misses=").append(updateTimestampsCacheMissCount) ",max query time=" + queryExecutionMaxTime +
.append( ",max query time=" ).append( queryExecutionMaxTime ) ",query plan cache hits=" + queryPlanCacheHitCount +
.append( ",query plan cache hits=" ).append( queryPlanCacheHitCount ) ",query plan cache misses=" + queryPlanCacheMissCount +
.append( ",query plan cache misses=" ).append( queryPlanCacheMissCount ) ']';
.append( ']' )
.toString();
} }
private EntityStatisticsImpl instantiateEntityStatistics(final String entityName) { private EntityStatisticsImpl instantiateEntityStatistics(final String entityName) {

View File

@ -32,7 +32,7 @@ public final class StatsNamedContainer<V> {
* Creates a bounded container - based on BoundedConcurrentHashMap * Creates a bounded container - based on BoundedConcurrentHashMap
*/ */
public StatsNamedContainer(int capacity, int concurrencyLevel) { public StatsNamedContainer(int capacity, int concurrencyLevel) {
this.map = new BoundedConcurrentHashMap( capacity, concurrencyLevel, BoundedConcurrentHashMap.Eviction.LRU ); this.map = new BoundedConcurrentHashMap<>( capacity, concurrencyLevel, BoundedConcurrentHashMap.Eviction.LRU );
} }
/** /**
@ -63,6 +63,7 @@ public final class StatsNamedContainer<V> {
* Most notably, the ConcurrentHashMap implementation might block other accesses for the sake of making * Most notably, the ConcurrentHashMap implementation might block other accesses for the sake of making
* sure the function is invoked at most once: we don't need this guarantee, and prefer to reduce risk of blocking. * sure the function is invoked at most once: we don't need this guarantee, and prefer to reduce risk of blocking.
*/ */
@SuppressWarnings("unchecked")
public V getOrCompute(final String key, final Function<String, V> function) { public V getOrCompute(final String key, final Function<String, V> function) {
final Object v1 = map.get( key ); final Object v1 = map.get( key );
if ( v1 != null ) { if ( v1 != null ) {