HHH-6033 - Migrate stats to api/spi/internal split
This commit is contained in:
parent
b14de70d7b
commit
f93d1412a4
|
@ -51,7 +51,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.proxy.EntityNotFoundDelegate;
|
||||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.spi.ServiceRegistry;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.TypeResolver;
|
||||
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
*/
|
||||
package org.hibernate.engine.jdbc.spi;
|
||||
import org.hibernate.ConnectionReleaseMode;
|
||||
import org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ package org.hibernate.engine.transaction.spi;
|
|||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.service.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
* Provides access to transactional services.
|
||||
|
|
|
@ -116,9 +116,9 @@ import org.hibernate.proxy.EntityNotFoundDelegate;
|
|||
import org.hibernate.service.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.service.spi.ServiceRegistry;
|
||||
import org.hibernate.stat.ConcurrentStatisticsImpl;
|
||||
import org.hibernate.stat.internal.ConcurrentStatisticsImpl;
|
||||
import org.hibernate.stat.Statistics;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaValidator;
|
||||
|
@ -205,9 +205,7 @@ public final class SessionFactoryImpl
|
|||
SessionFactoryObserver observer) throws HibernateException {
|
||||
LOG.buildingSessionFactory();
|
||||
|
||||
this.statistics = new ConcurrentStatisticsImpl( this );
|
||||
getStatistics().setStatisticsEnabled( settings.isStatisticsEnabled() );
|
||||
LOG.debugf("Statistics initialized [enabled=%s]", settings.isStatisticsEnabled());
|
||||
this.statistics = buildStatistics( settings, serviceRegistry );
|
||||
|
||||
this.properties = new Properties();
|
||||
this.properties.putAll( cfg.getProperties() );
|
||||
|
@ -474,6 +472,13 @@ public final class SessionFactoryImpl
|
|||
this.observer.sessionFactoryCreated( this );
|
||||
}
|
||||
|
||||
private Statistics buildStatistics(Settings settings, ServiceRegistry serviceRegistry) {
|
||||
Statistics statistics = new ConcurrentStatisticsImpl( this );
|
||||
getStatistics().setStatisticsEnabled( settings.isStatisticsEnabled() );
|
||||
LOG.debugf("Statistics initialized [enabled=%s]", settings.isStatisticsEnabled());
|
||||
return statistics;
|
||||
}
|
||||
|
||||
public TransactionEnvironment getTransactionEnvironment() {
|
||||
return transactionEnvironment;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import java.sql.Blob;
|
|||
import java.sql.Clob;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -122,8 +121,6 @@ import org.hibernate.event.ReplicateEvent;
|
|||
import org.hibernate.event.ReplicateEventListener;
|
||||
import org.hibernate.event.SaveOrUpdateEvent;
|
||||
import org.hibernate.event.SaveOrUpdateEventListener;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.jdbc.WorkExecutorVisitable;
|
||||
import org.hibernate.jdbc.ReturningWork;
|
||||
|
@ -139,7 +136,7 @@ import org.hibernate.pretty.MessageHelper;
|
|||
import org.hibernate.proxy.HibernateProxy;
|
||||
import org.hibernate.proxy.LazyInitializer;
|
||||
import org.hibernate.stat.SessionStatistics;
|
||||
import org.hibernate.stat.SessionStatisticsImpl;
|
||||
import org.hibernate.stat.internal.SessionStatisticsImpl;
|
||||
import org.hibernate.type.SerializationException;
|
||||
import org.hibernate.type.Type;
|
||||
import org.jboss.logging.Logger;
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
|||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
import org.hibernate.service.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.service.spi.ServiceRegistry;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
|
|
@ -12,7 +12,8 @@ import org.hibernate.stat.EntityStatistics;
|
|||
import org.hibernate.stat.QueryStatistics;
|
||||
import org.hibernate.stat.SecondLevelCacheStatistics;
|
||||
import org.hibernate.stat.Statistics;
|
||||
import org.hibernate.stat.StatisticsImpl;
|
||||
import org.hibernate.stat.internal.ConcurrentStatisticsImpl;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
|
@ -54,7 +55,7 @@ public class StatisticsService implements StatisticsServiceMBean {
|
|||
|
||||
SessionFactory sf;
|
||||
String sfJNDIName;
|
||||
Statistics stats = new StatisticsImpl();
|
||||
Statistics stats = new ConcurrentStatisticsImpl();
|
||||
|
||||
/**
|
||||
* @see StatisticsServiceMBean#setSessionFactoryJNDIName(java.lang.String)
|
||||
|
@ -93,7 +94,7 @@ public class StatisticsService implements StatisticsServiceMBean {
|
|||
public void setSessionFactory(SessionFactory sf) {
|
||||
this.sf = sf;
|
||||
if (sf == null) {
|
||||
stats = new StatisticsImpl();
|
||||
stats = new ConcurrentStatisticsImpl();
|
||||
}
|
||||
else {
|
||||
stats = sf.getStatistics();
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,16 +20,15 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Collection related statistics
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public interface CollectionStatistics extends Serializable {
|
||||
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
|
||||
/**
|
||||
* Collection related statistics
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class CollectionStatisticsImpl extends CategorizedStatistics implements CollectionStatistics {
|
||||
|
||||
CollectionStatisticsImpl(String role) {
|
||||
super(role);
|
||||
}
|
||||
|
||||
long loadCount;
|
||||
long fetchCount;
|
||||
long updateCount;
|
||||
long removeCount;
|
||||
long recreateCount;
|
||||
|
||||
public long getLoadCount() {
|
||||
return loadCount;
|
||||
}
|
||||
|
||||
public long getFetchCount() {
|
||||
return fetchCount;
|
||||
}
|
||||
|
||||
public long getRecreateCount() {
|
||||
return recreateCount;
|
||||
}
|
||||
|
||||
public long getRemoveCount() {
|
||||
return removeCount;
|
||||
}
|
||||
|
||||
public long getUpdateCount() {
|
||||
return updateCount;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new StringBuilder()
|
||||
.append("CollectionStatistics")
|
||||
.append("[loadCount=").append(this.loadCount)
|
||||
.append(",fetchCount=").append(this.fetchCount)
|
||||
.append(",recreateCount=").append(this.recreateCount)
|
||||
.append(",removeCount=").append(this.removeCount)
|
||||
.append(",updateCount=").append(this.updateCount)
|
||||
.append(']')
|
||||
.toString();
|
||||
}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
package org.hibernate.stat;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import org.hibernate.cache.CacheKey;
|
||||
import org.hibernate.cache.Region;
|
||||
|
||||
/**
|
||||
* Second level cache statistics of a specific region
|
||||
*
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class ConcurrentSecondLevelCacheStatisticsImpl extends CategorizedStatistics implements SecondLevelCacheStatistics {
|
||||
|
||||
private final transient Region region;
|
||||
private AtomicLong hitCount = new AtomicLong();
|
||||
private AtomicLong missCount = new AtomicLong();
|
||||
private AtomicLong putCount = new AtomicLong();
|
||||
|
||||
ConcurrentSecondLevelCacheStatisticsImpl(Region region) {
|
||||
super(region.getName());
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
public long getHitCount() {
|
||||
return hitCount.get();
|
||||
}
|
||||
|
||||
public long getMissCount() {
|
||||
return missCount.get();
|
||||
}
|
||||
|
||||
public long getPutCount() {
|
||||
return putCount.get();
|
||||
}
|
||||
|
||||
public long getElementCountInMemory() {
|
||||
return region.getElementCountInMemory();
|
||||
}
|
||||
|
||||
public long getElementCountOnDisk() {
|
||||
return region.getElementCountOnDisk();
|
||||
}
|
||||
|
||||
public long getSizeInMemory() {
|
||||
return region.getSizeInMemory();
|
||||
}
|
||||
|
||||
public Map getEntries() {
|
||||
Map map = new HashMap();
|
||||
Iterator iter = region.toMap().entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry me = (Map.Entry) iter.next();
|
||||
map.put(((CacheKey) me.getKey()).getKey(), me.getValue());
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder buf = new StringBuilder()
|
||||
.append("SecondLevelCacheStatistics")
|
||||
.append("[hitCount=").append(this.hitCount)
|
||||
.append(",missCount=").append(this.missCount)
|
||||
.append(",putCount=").append(this.putCount);
|
||||
//not sure if this would ever be null but wanted to be careful
|
||||
if (region != null) {
|
||||
buf.append(",elementCountInMemory=").append(this.getElementCountInMemory())
|
||||
.append(",elementCountOnDisk=").append(this.getElementCountOnDisk())
|
||||
.append(",sizeInMemory=").append(this.getSizeInMemory());
|
||||
}
|
||||
buf.append(']');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
void incrementHitCount() {
|
||||
hitCount.getAndIncrement();
|
||||
}
|
||||
|
||||
void incrementMissCount() {
|
||||
missCount.getAndIncrement();
|
||||
}
|
||||
|
||||
void incrementPutCount() {
|
||||
putCount.getAndIncrement();
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,16 +20,15 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Entity related statistics
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public interface EntityStatistics extends Serializable {
|
||||
long getDeleteCount();
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Entity related statistics
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class EntityStatisticsImpl extends CategorizedStatistics implements EntityStatistics {
|
||||
|
||||
EntityStatisticsImpl(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
long loadCount;
|
||||
long updateCount;
|
||||
long insertCount;
|
||||
long deleteCount;
|
||||
long fetchCount;
|
||||
long optimisticFailureCount;
|
||||
|
||||
public long getDeleteCount() {
|
||||
return deleteCount;
|
||||
}
|
||||
|
||||
public long getInsertCount() {
|
||||
return insertCount;
|
||||
}
|
||||
|
||||
public long getLoadCount() {
|
||||
return loadCount;
|
||||
}
|
||||
|
||||
public long getUpdateCount() {
|
||||
return updateCount;
|
||||
}
|
||||
|
||||
public long getFetchCount() {
|
||||
return fetchCount;
|
||||
}
|
||||
|
||||
public long getOptimisticFailureCount() {
|
||||
return optimisticFailureCount;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new StringBuilder()
|
||||
.append("EntityStatistics")
|
||||
.append("[loadCount=").append(this.loadCount)
|
||||
.append(",updateCount=").append(this.updateCount)
|
||||
.append(",insertCount=").append(this.insertCount)
|
||||
.append(",deleteCount=").append(this.deleteCount)
|
||||
.append(",fetchCount=").append(this.fetchCount)
|
||||
.append(",optimisticLockFailureCount=").append(this.optimisticFailureCount)
|
||||
.append(']')
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,9 +20,9 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,6 @@ import java.io.Serializable;
|
|||
* Note that for a cached query, the cache miss is equals to the db count
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public interface QueryStatistics extends Serializable {
|
||||
long getExecutionCount();
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
|
||||
/**
|
||||
* Query statistics (HQL and SQL)
|
||||
* <p/>
|
||||
* Note that for a cached query, the cache miss is equals to the db count
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class QueryStatisticsImpl extends CategorizedStatistics implements QueryStatistics {
|
||||
|
||||
/*package*/
|
||||
long cacheHitCount;
|
||||
/*package*/
|
||||
long cacheMissCount;
|
||||
/*package*/
|
||||
long cachePutCount;
|
||||
private long executionCount;
|
||||
private long executionRowCount;
|
||||
private long executionAvgTime;
|
||||
private long executionMaxTime;
|
||||
private long executionMinTime = Long.MAX_VALUE;
|
||||
|
||||
QueryStatisticsImpl(String query) {
|
||||
super(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* queries executed to the DB
|
||||
*/
|
||||
public long getExecutionCount() {
|
||||
return executionCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries retrieved successfully from the cache
|
||||
*/
|
||||
public long getCacheHitCount() {
|
||||
return cacheHitCount;
|
||||
}
|
||||
|
||||
public long getCachePutCount() {
|
||||
return cachePutCount;
|
||||
}
|
||||
|
||||
public long getCacheMissCount() {
|
||||
return cacheMissCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of lines returned by all the executions of this query (from DB)
|
||||
* For now, {@link org.hibernate.Query#iterate()}
|
||||
* and {@link org.hibernate.Query#scroll()()} do not fill this statistic
|
||||
*
|
||||
* @return The number of rows cumulatively returned by the given query; iterate
|
||||
* and scroll queries do not effect this total as their number of returned rows
|
||||
* is not known at execution time.
|
||||
*/
|
||||
public long getExecutionRowCount() {
|
||||
return executionRowCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* average time in ms taken by the execution of this query onto the DB
|
||||
*/
|
||||
public long getExecutionAvgTime() {
|
||||
return executionAvgTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* max time in ms taken by the execution of this query onto the DB
|
||||
*/
|
||||
public long getExecutionMaxTime() {
|
||||
return executionMaxTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* min time in ms taken by the execution of this query onto the DB
|
||||
*/
|
||||
public long getExecutionMinTime() {
|
||||
return executionMinTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* add statistics report of a DB query
|
||||
*
|
||||
* @param rows rows count returned
|
||||
* @param time time taken
|
||||
*/
|
||||
void executed(long rows, long time) {
|
||||
if (time < executionMinTime) executionMinTime = time;
|
||||
if (time > executionMaxTime) executionMaxTime = time;
|
||||
executionAvgTime = (executionAvgTime * executionCount + time) / (executionCount + 1);
|
||||
executionCount++;
|
||||
executionRowCount += rows;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return new StringBuilder()
|
||||
.append("QueryStatistics")
|
||||
.append("[cacheHitCount=").append(this.cacheHitCount)
|
||||
.append(",cacheMissCount=").append(this.cacheMissCount)
|
||||
.append(",cachePutCount=").append(this.cachePutCount)
|
||||
.append(",executionCount=").append(this.executionCount)
|
||||
.append(",executionRowCount=").append(this.executionRowCount)
|
||||
.append(",executionAvgTime=").append(this.executionAvgTime)
|
||||
.append(",executionMaxTime=").append(this.executionMaxTime)
|
||||
.append(",executionMinTime=").append(this.executionMinTime)
|
||||
.append(']')
|
||||
.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,9 +20,9 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -30,7 +30,6 @@ import java.util.Map;
|
|||
* Second level cache statistics of a specific region
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public interface SecondLevelCacheStatistics extends Serializable {
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,9 +20,9 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
|
@ -31,7 +31,6 @@ import java.util.Set;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public interface SessionStatistics {
|
||||
|
||||
/**
|
||||
* Get the number of entity instances associated with the session
|
||||
*/
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,16 +20,12 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Statistics for a particular <tt>SessionFactory</tt>.
|
||||
* Beware of milliseconds metrics, they are depdendent of the JVM precision:
|
||||
* you may then encounter a 10 ms approximation dending on you OS platform.
|
||||
* Exposes statistics for a particular {@link org.hibernate.SessionFactory}. Beware of milliseconds metrics, they
|
||||
* are dependent of the JVM precision: you may then encounter a 10 ms approximation depending on you OS platform.
|
||||
* Please refer to the JVM documentation for more information.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
|
|
|
@ -1,666 +0,0 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.hibernate.HibernateLogger;
|
||||
import org.hibernate.cache.Region;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* @see org.hibernate.stat.Statistics
|
||||
*
|
||||
* @author Gavin King
|
||||
*
|
||||
* @deprecated Use {@link org.hibernate.stat.ConcurrentStatisticsImpl} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public class StatisticsImpl implements Statistics, StatisticsImplementor {
|
||||
|
||||
//TODO: we should provide some way to get keys of collection of statistics to make it easier to retrieve from a GUI perspective
|
||||
|
||||
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, StatisticsImpl.class.getName());
|
||||
|
||||
private SessionFactoryImplementor sessionFactory;
|
||||
|
||||
private boolean isStatisticsEnabled;
|
||||
private long startTime;
|
||||
private long sessionOpenCount;
|
||||
private long sessionCloseCount;
|
||||
private long flushCount;
|
||||
private long connectCount;
|
||||
|
||||
private long prepareStatementCount;
|
||||
private long closeStatementCount;
|
||||
|
||||
private long entityLoadCount;
|
||||
private long entityUpdateCount;
|
||||
private long entityInsertCount;
|
||||
private long entityDeleteCount;
|
||||
private long entityFetchCount;
|
||||
private long collectionLoadCount;
|
||||
private long collectionUpdateCount;
|
||||
private long collectionRemoveCount;
|
||||
private long collectionRecreateCount;
|
||||
private long collectionFetchCount;
|
||||
|
||||
private long secondLevelCacheHitCount;
|
||||
private long secondLevelCacheMissCount;
|
||||
private long secondLevelCachePutCount;
|
||||
|
||||
private long queryExecutionCount;
|
||||
private long queryExecutionMaxTime;
|
||||
private String queryExecutionMaxTimeQueryString;
|
||||
private long queryCacheHitCount;
|
||||
private long queryCacheMissCount;
|
||||
private long queryCachePutCount;
|
||||
|
||||
private long commitedTransactionCount;
|
||||
private long transactionCount;
|
||||
|
||||
private long optimisticFailureCount;
|
||||
|
||||
/** second level cache statistics per region */
|
||||
private final Map secondLevelCacheStatistics = new HashMap();
|
||||
/** entity statistics per name */
|
||||
private final Map entityStatistics = new HashMap();
|
||||
/** collection statistics per name */
|
||||
private final Map collectionStatistics = new HashMap();
|
||||
/** entity statistics per query string (HQL or SQL) */
|
||||
private final Map queryStatistics = new HashMap();
|
||||
|
||||
public StatisticsImpl() {
|
||||
clear();
|
||||
}
|
||||
|
||||
public StatisticsImpl(SessionFactoryImplementor sessionFactory) {
|
||||
clear();
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* reset all statistics
|
||||
*/
|
||||
public synchronized void clear() {
|
||||
secondLevelCacheHitCount = 0;
|
||||
secondLevelCacheMissCount = 0;
|
||||
secondLevelCachePutCount = 0;
|
||||
|
||||
sessionCloseCount = 0;
|
||||
sessionOpenCount = 0;
|
||||
flushCount = 0;
|
||||
connectCount = 0;
|
||||
|
||||
prepareStatementCount = 0;
|
||||
closeStatementCount = 0;
|
||||
|
||||
entityDeleteCount = 0;
|
||||
entityInsertCount = 0;
|
||||
entityUpdateCount = 0;
|
||||
entityLoadCount = 0;
|
||||
entityFetchCount = 0;
|
||||
|
||||
collectionRemoveCount = 0;
|
||||
collectionUpdateCount = 0;
|
||||
collectionRecreateCount = 0;
|
||||
collectionLoadCount = 0;
|
||||
collectionFetchCount = 0;
|
||||
|
||||
queryExecutionCount = 0;
|
||||
queryCacheHitCount = 0;
|
||||
queryExecutionMaxTime = 0;
|
||||
queryExecutionMaxTimeQueryString = null;
|
||||
queryCacheMissCount = 0;
|
||||
queryCachePutCount = 0;
|
||||
|
||||
transactionCount = 0;
|
||||
commitedTransactionCount = 0;
|
||||
|
||||
optimisticFailureCount = 0;
|
||||
|
||||
secondLevelCacheStatistics.clear();
|
||||
entityStatistics.clear();
|
||||
collectionStatistics.clear();
|
||||
queryStatistics.clear();
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public synchronized void openSession() {
|
||||
sessionOpenCount++;
|
||||
}
|
||||
|
||||
public synchronized void closeSession() {
|
||||
sessionCloseCount++;
|
||||
}
|
||||
|
||||
public synchronized void flush() {
|
||||
flushCount++;
|
||||
}
|
||||
|
||||
public synchronized void connect() {
|
||||
connectCount++;
|
||||
}
|
||||
|
||||
public synchronized void loadEntity(String entityName) {
|
||||
entityLoadCount++;
|
||||
((EntityStatisticsImpl) getEntityStatistics(entityName)).loadCount++;
|
||||
}
|
||||
|
||||
public synchronized void fetchEntity(String entityName) {
|
||||
entityFetchCount++;
|
||||
((EntityStatisticsImpl) getEntityStatistics(entityName)).fetchCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* find entity statistics per name
|
||||
*
|
||||
* @param entityName entity name
|
||||
* @return EntityStatistics object
|
||||
*/
|
||||
public synchronized EntityStatistics getEntityStatistics(String entityName) {
|
||||
EntityStatisticsImpl es = (EntityStatisticsImpl) entityStatistics.get(entityName);
|
||||
if (es == null) {
|
||||
es = new EntityStatisticsImpl(entityName);
|
||||
entityStatistics.put(entityName, es);
|
||||
}
|
||||
return es;
|
||||
}
|
||||
|
||||
public synchronized void updateEntity(String entityName) {
|
||||
entityUpdateCount++;
|
||||
EntityStatisticsImpl es = (EntityStatisticsImpl) getEntityStatistics(entityName);
|
||||
es.updateCount++;
|
||||
}
|
||||
|
||||
public synchronized void insertEntity(String entityName) {
|
||||
entityInsertCount++;
|
||||
EntityStatisticsImpl es = (EntityStatisticsImpl) getEntityStatistics(entityName);
|
||||
es.insertCount++;
|
||||
}
|
||||
|
||||
public synchronized void deleteEntity(String entityName) {
|
||||
entityDeleteCount++;
|
||||
EntityStatisticsImpl es = (EntityStatisticsImpl) getEntityStatistics(entityName);
|
||||
es.deleteCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection statistics per role
|
||||
*
|
||||
* @param role collection role
|
||||
* @return CollectionStatistics
|
||||
*/
|
||||
public synchronized CollectionStatistics getCollectionStatistics(String role) {
|
||||
CollectionStatisticsImpl cs = (CollectionStatisticsImpl) collectionStatistics.get(role);
|
||||
if (cs==null) {
|
||||
cs = new CollectionStatisticsImpl(role);
|
||||
collectionStatistics.put(role, cs);
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
|
||||
public synchronized void loadCollection(String role) {
|
||||
collectionLoadCount++;
|
||||
((CollectionStatisticsImpl) getCollectionStatistics(role)).loadCount++;
|
||||
}
|
||||
|
||||
public synchronized void fetchCollection(String role) {
|
||||
collectionFetchCount++;
|
||||
((CollectionStatisticsImpl) getCollectionStatistics(role)).fetchCount++;
|
||||
}
|
||||
|
||||
public synchronized void updateCollection(String role) {
|
||||
collectionUpdateCount++;
|
||||
((CollectionStatisticsImpl) getCollectionStatistics(role)).updateCount++;
|
||||
}
|
||||
|
||||
public synchronized void recreateCollection(String role) {
|
||||
collectionRecreateCount++;
|
||||
((CollectionStatisticsImpl) getCollectionStatistics(role)).recreateCount++;
|
||||
}
|
||||
|
||||
public synchronized void removeCollection(String role) {
|
||||
collectionRemoveCount++;
|
||||
((CollectionStatisticsImpl) getCollectionStatistics(role)).removeCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Second level cache statistics per region
|
||||
*
|
||||
* @param regionName region name
|
||||
* @return SecondLevelCacheStatistics
|
||||
*/
|
||||
public synchronized SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName) {
|
||||
SecondLevelCacheStatisticsImpl slcs = (SecondLevelCacheStatisticsImpl) secondLevelCacheStatistics.get(regionName);
|
||||
if ( slcs == null ) {
|
||||
if ( sessionFactory == null ) {
|
||||
return null;
|
||||
}
|
||||
Region region = sessionFactory.getSecondLevelCacheRegion( regionName );
|
||||
if ( region == null ) {
|
||||
return null;
|
||||
}
|
||||
slcs = new SecondLevelCacheStatisticsImpl(region);
|
||||
secondLevelCacheStatistics.put( regionName, slcs );
|
||||
}
|
||||
return slcs;
|
||||
}
|
||||
|
||||
public synchronized void secondLevelCachePut(String regionName) {
|
||||
secondLevelCachePutCount++;
|
||||
((SecondLevelCacheStatisticsImpl) getSecondLevelCacheStatistics(regionName)).putCount++;
|
||||
}
|
||||
|
||||
public synchronized void secondLevelCacheHit(String regionName) {
|
||||
secondLevelCacheHitCount++;
|
||||
((SecondLevelCacheStatisticsImpl) getSecondLevelCacheStatistics(regionName)).hitCount++;
|
||||
}
|
||||
|
||||
public synchronized void secondLevelCacheMiss(String regionName) {
|
||||
secondLevelCacheMissCount++;
|
||||
((SecondLevelCacheStatisticsImpl) getSecondLevelCacheStatistics(regionName)).missCount++;
|
||||
}
|
||||
|
||||
public synchronized void queryExecuted(String hql, int rows, long time) {
|
||||
queryExecutionCount++;
|
||||
if (queryExecutionMaxTime<time) {
|
||||
queryExecutionMaxTime=time;
|
||||
queryExecutionMaxTimeQueryString = hql;
|
||||
}
|
||||
if (hql!=null) {
|
||||
QueryStatisticsImpl qs = (QueryStatisticsImpl) getQueryStatistics(hql);
|
||||
qs.executed(rows, time);
|
||||
LOG.hql(hql, new Long(time), new Long(rows));
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void queryCacheHit(String hql, String regionName) {
|
||||
queryCacheHitCount++;
|
||||
if (hql!=null) {
|
||||
QueryStatisticsImpl qs = (QueryStatisticsImpl) getQueryStatistics(hql);
|
||||
qs.cacheHitCount++;
|
||||
}
|
||||
SecondLevelCacheStatisticsImpl slcs = (SecondLevelCacheStatisticsImpl) getSecondLevelCacheStatistics(regionName);
|
||||
slcs.hitCount++;
|
||||
}
|
||||
|
||||
public synchronized void queryCacheMiss(String hql, String regionName) {
|
||||
queryCacheMissCount++;
|
||||
if (hql!=null) {
|
||||
QueryStatisticsImpl qs = (QueryStatisticsImpl) getQueryStatistics(hql);
|
||||
qs.cacheMissCount++;
|
||||
}
|
||||
SecondLevelCacheStatisticsImpl slcs = (SecondLevelCacheStatisticsImpl) getSecondLevelCacheStatistics(regionName);
|
||||
slcs.missCount++;
|
||||
}
|
||||
|
||||
public synchronized void queryCachePut(String hql, String regionName) {
|
||||
queryCachePutCount++;
|
||||
if (hql!=null) {
|
||||
QueryStatisticsImpl qs = (QueryStatisticsImpl) getQueryStatistics(hql);
|
||||
qs.cachePutCount++;
|
||||
}
|
||||
SecondLevelCacheStatisticsImpl slcs = (SecondLevelCacheStatisticsImpl) getSecondLevelCacheStatistics(regionName);
|
||||
slcs.putCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query statistics from query string (HQL or SQL)
|
||||
*
|
||||
* @param queryString query string
|
||||
* @return QueryStatistics
|
||||
*/
|
||||
public synchronized QueryStatistics getQueryStatistics(String queryString) {
|
||||
QueryStatisticsImpl qs = (QueryStatisticsImpl) queryStatistics.get(queryString);
|
||||
if (qs==null) {
|
||||
qs = new QueryStatisticsImpl(queryString);
|
||||
queryStatistics.put(queryString, qs);
|
||||
}
|
||||
return qs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return entity deletion count
|
||||
*/
|
||||
public long getEntityDeleteCount() {
|
||||
return entityDeleteCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return entity insertion count
|
||||
*/
|
||||
public long getEntityInsertCount() {
|
||||
return entityInsertCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return entity load (from DB)
|
||||
*/
|
||||
public long getEntityLoadCount() {
|
||||
return entityLoadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return entity fetch (from DB)
|
||||
*/
|
||||
public long getEntityFetchCount() {
|
||||
return entityFetchCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return entity update
|
||||
*/
|
||||
public long getEntityUpdateCount() {
|
||||
return entityUpdateCount;
|
||||
}
|
||||
|
||||
public long getQueryExecutionCount() {
|
||||
return queryExecutionCount;
|
||||
}
|
||||
|
||||
public long getQueryCacheHitCount() {
|
||||
return queryCacheHitCount;
|
||||
}
|
||||
|
||||
public long getQueryCacheMissCount() {
|
||||
return queryCacheMissCount;
|
||||
}
|
||||
|
||||
public long getQueryCachePutCount() {
|
||||
return queryCachePutCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return flush
|
||||
*/
|
||||
public long getFlushCount() {
|
||||
return flushCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return session connect
|
||||
*/
|
||||
public long getConnectCount() {
|
||||
return connectCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return second level cache hit
|
||||
*/
|
||||
public long getSecondLevelCacheHitCount() {
|
||||
return secondLevelCacheHitCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return second level cache miss
|
||||
*/
|
||||
public long getSecondLevelCacheMissCount() {
|
||||
return secondLevelCacheMissCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return second level cache put
|
||||
*/
|
||||
public long getSecondLevelCachePutCount() {
|
||||
return secondLevelCachePutCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return session closing
|
||||
*/
|
||||
public long getSessionCloseCount() {
|
||||
return sessionCloseCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return session opening
|
||||
*/
|
||||
public long getSessionOpenCount() {
|
||||
return sessionOpenCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return collection loading (from DB)
|
||||
*/
|
||||
public long getCollectionLoadCount() {
|
||||
return collectionLoadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return collection fetching (from DB)
|
||||
*/
|
||||
public long getCollectionFetchCount() {
|
||||
return collectionFetchCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return collection update
|
||||
*/
|
||||
public long getCollectionUpdateCount() {
|
||||
return collectionUpdateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return collection removal
|
||||
* FIXME: even if isInverse="true"?
|
||||
*/
|
||||
public long getCollectionRemoveCount() {
|
||||
return collectionRemoveCount;
|
||||
}
|
||||
/**
|
||||
* @return collection recreation
|
||||
*/
|
||||
public long getCollectionRecreateCount() {
|
||||
return collectionRecreateCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return start time in ms (JVM standards {@link System#currentTimeMillis()})
|
||||
*/
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* log in info level the main statistics
|
||||
*/
|
||||
public void logSummary() {
|
||||
LOG.loggingStatistics();
|
||||
LOG.startTime(startTime);
|
||||
LOG.sessionsOpened(sessionOpenCount);
|
||||
LOG.sessionsClosed(sessionCloseCount);
|
||||
LOG.transactions(transactionCount);
|
||||
LOG.successfulTransactions(commitedTransactionCount);
|
||||
LOG.optimisticLockFailures(optimisticFailureCount);
|
||||
LOG.flushes(flushCount);
|
||||
LOG.connectionsObtained(connectCount);
|
||||
LOG.statementsPrepared(prepareStatementCount);
|
||||
LOG.statementsClosed(closeStatementCount);
|
||||
LOG.secondLevelCachePuts(secondLevelCachePutCount);
|
||||
LOG.secondLevelCacheHits(secondLevelCacheHitCount);
|
||||
LOG.secondLevelCacheMisses(secondLevelCacheMissCount);
|
||||
LOG.entitiesLoaded(entityLoadCount);
|
||||
LOG.entitiesUpdated(entityUpdateCount);
|
||||
LOG.entitiesInserted(entityInsertCount);
|
||||
LOG.entitiesDeleted(entityDeleteCount);
|
||||
LOG.entitiesFetched(entityFetchCount);
|
||||
LOG.collectionsLoaded(collectionLoadCount);
|
||||
LOG.collectionsUpdated(collectionUpdateCount);
|
||||
LOG.collectionsRemoved(collectionRemoveCount);
|
||||
LOG.collectionsRecreated(collectionRecreateCount);
|
||||
LOG.collectionsFetched(collectionFetchCount);
|
||||
LOG.queriesExecuted(queryExecutionCount);
|
||||
LOG.queryCachePuts(queryCachePutCount);
|
||||
LOG.queryCacheHits(queryCacheHitCount);
|
||||
LOG.queryCacheMisses(queryCacheMissCount);
|
||||
LOG.maxQueryTime(queryExecutionMaxTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Are statistics logged
|
||||
*/
|
||||
public boolean isStatisticsEnabled() {
|
||||
return isStatisticsEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable statistics logs (this is a dynamic parameter)
|
||||
*/
|
||||
public void setStatisticsEnabled(boolean b) {
|
||||
isStatisticsEnabled = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the max query execution time,
|
||||
* for all queries
|
||||
*/
|
||||
public long getQueryExecutionMaxTime() {
|
||||
return queryExecutionMaxTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all executed query strings
|
||||
*/
|
||||
public String[] getQueries() {
|
||||
return ArrayHelper.toStringArray( queryStatistics.keySet() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of all entities
|
||||
*/
|
||||
public String[] getEntityNames() {
|
||||
if (sessionFactory==null) {
|
||||
return ArrayHelper.toStringArray( entityStatistics.keySet() );
|
||||
}
|
||||
else {
|
||||
return ArrayHelper.toStringArray( sessionFactory.getAllClassMetadata().keySet() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of all collection roles
|
||||
*/
|
||||
public String[] getCollectionRoleNames() {
|
||||
if (sessionFactory==null) {
|
||||
return ArrayHelper.toStringArray( collectionStatistics.keySet() );
|
||||
}
|
||||
else {
|
||||
return ArrayHelper.toStringArray( sessionFactory.getAllCollectionMetadata().keySet() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all second-level cache region names
|
||||
*/
|
||||
public String[] getSecondLevelCacheRegionNames() {
|
||||
if (sessionFactory==null) {
|
||||
return ArrayHelper.toStringArray( secondLevelCacheStatistics.keySet() );
|
||||
}
|
||||
else {
|
||||
return ArrayHelper.toStringArray( sessionFactory.getAllSecondLevelCacheRegions().keySet() );
|
||||
}
|
||||
}
|
||||
|
||||
public void endTransaction(boolean success) {
|
||||
transactionCount++;
|
||||
if (success) commitedTransactionCount++;
|
||||
}
|
||||
|
||||
public long getSuccessfulTransactionCount() {
|
||||
return commitedTransactionCount;
|
||||
}
|
||||
|
||||
public long getTransactionCount() {
|
||||
return transactionCount;
|
||||
}
|
||||
|
||||
public void closeStatement() {
|
||||
closeStatementCount++;
|
||||
}
|
||||
|
||||
public void prepareStatement() {
|
||||
prepareStatementCount++;
|
||||
}
|
||||
|
||||
public long getCloseStatementCount() {
|
||||
return closeStatementCount;
|
||||
}
|
||||
|
||||
public long getPrepareStatementCount() {
|
||||
return prepareStatementCount;
|
||||
}
|
||||
|
||||
public void optimisticFailure(String entityName) {
|
||||
optimisticFailureCount++;
|
||||
((EntityStatisticsImpl) getEntityStatistics(entityName)).optimisticFailureCount++;
|
||||
}
|
||||
|
||||
public long getOptimisticFailureCount() {
|
||||
return optimisticFailureCount;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuffer()
|
||||
.append("Statistics[")
|
||||
.append("start time=").append(startTime)
|
||||
.append(",sessions opened=").append(sessionOpenCount)
|
||||
.append(",sessions closed=").append(sessionCloseCount)
|
||||
.append(",transactions=").append(transactionCount)
|
||||
.append(",successful transactions=").append(commitedTransactionCount)
|
||||
.append(",optimistic lock failures=").append(optimisticFailureCount)
|
||||
.append(",flushes=").append(flushCount)
|
||||
.append(",connections obtained=").append(connectCount)
|
||||
.append(",statements prepared=").append(prepareStatementCount)
|
||||
.append(",statements closed=").append(closeStatementCount)
|
||||
.append(",second level cache puts=").append(secondLevelCachePutCount)
|
||||
.append(",second level cache hits=").append(secondLevelCacheHitCount)
|
||||
.append(",second level cache misses=").append(secondLevelCacheMissCount)
|
||||
.append(",entities loaded=").append(entityLoadCount)
|
||||
.append(",entities updated=").append(entityUpdateCount)
|
||||
.append(",entities inserted=").append(entityInsertCount)
|
||||
.append(",entities deleted=").append(entityDeleteCount)
|
||||
.append(",entities fetched=").append(entityFetchCount)
|
||||
.append(",collections loaded=").append(collectionLoadCount)
|
||||
.append(",collections updated=").append(collectionUpdateCount)
|
||||
.append(",collections removed=").append(collectionRemoveCount)
|
||||
.append(",collections recreated=").append(collectionRecreateCount)
|
||||
.append(",collections fetched=").append(collectionFetchCount)
|
||||
.append(",queries executed to database=").append(queryExecutionCount)
|
||||
.append(",query cache puts=").append(queryCachePutCount)
|
||||
.append(",query cache hits=").append(queryCacheHitCount)
|
||||
.append(",query cache misses=").append(queryCacheMissCount)
|
||||
.append(",max query time=").append(queryExecutionMaxTime)
|
||||
.append(']')
|
||||
.toString();
|
||||
}
|
||||
|
||||
public String getQueryExecutionMaxTimeQueryString() {
|
||||
return queryExecutionMaxTimeQueryString;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,14 +20,13 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
package org.hibernate.stat.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Statistics for a particular "category" (a named entity,
|
||||
* collection role, second level cache region or query).
|
||||
* Statistics for a particular "category" (a named entity, collection role, second level cache region or query).
|
||||
*
|
||||
* @author Gavin King
|
||||
*/
|
|
@ -1,13 +1,38 @@
|
|||
package org.hibernate.stat;
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2010-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.stat.internal;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.hibernate.stat.CollectionStatistics;
|
||||
|
||||
/**
|
||||
* Collection related statistics
|
||||
*
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class ConcurrentCollectionStatisticsImpl extends CategorizedStatistics implements CollectionStatistics {
|
||||
|
||||
ConcurrentCollectionStatisticsImpl(String role) {
|
||||
super(role);
|
||||
}
|
|
@ -1,6 +1,31 @@
|
|||
package org.hibernate.stat;
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.stat.internal;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.hibernate.stat.EntityStatistics;
|
||||
|
||||
/**
|
||||
* Entity related statistics
|
|
@ -1,9 +1,35 @@
|
|||
package org.hibernate.stat;
|
||||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.stat.internal;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import org.hibernate.stat.QueryStatistics;
|
||||
|
||||
/**
|
||||
* Query statistics (HQL and SQL)
|
||||
* <p/>
|
||||
|
@ -12,7 +38,6 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|||
* @author Alex Snaps
|
||||
*/
|
||||
public class ConcurrentQueryStatisticsImpl extends CategorizedStatistics implements QueryStatistics {
|
||||
|
||||
private final AtomicLong cacheHitCount = new AtomicLong();
|
||||
private final AtomicLong cacheMissCount = new AtomicLong();
|
||||
private final AtomicLong cachePutCount = new AtomicLong();
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,42 +20,44 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
package org.hibernate.stat.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.hibernate.cache.CacheKey;
|
||||
import org.hibernate.cache.Region;
|
||||
import org.hibernate.stat.SecondLevelCacheStatistics;
|
||||
|
||||
/**
|
||||
* Second level cache statistics of a specific region
|
||||
*
|
||||
* @author Gavin King
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
public class SecondLevelCacheStatisticsImpl extends CategorizedStatistics implements SecondLevelCacheStatistics {
|
||||
public class ConcurrentSecondLevelCacheStatisticsImpl extends CategorizedStatistics implements SecondLevelCacheStatistics {
|
||||
private final transient Region region;
|
||||
private AtomicLong hitCount = new AtomicLong();
|
||||
private AtomicLong missCount = new AtomicLong();
|
||||
private AtomicLong putCount = new AtomicLong();
|
||||
|
||||
private transient Region region;
|
||||
long hitCount;
|
||||
long missCount;
|
||||
long putCount;
|
||||
|
||||
SecondLevelCacheStatisticsImpl(Region region) {
|
||||
super(region.getName());
|
||||
ConcurrentSecondLevelCacheStatisticsImpl(Region region) {
|
||||
super( region.getName() );
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
public long getHitCount() {
|
||||
return hitCount;
|
||||
return hitCount.get();
|
||||
}
|
||||
|
||||
public long getMissCount() {
|
||||
return missCount;
|
||||
return missCount.get();
|
||||
}
|
||||
|
||||
public long getPutCount() {
|
||||
return putCount;
|
||||
return putCount.get();
|
||||
}
|
||||
|
||||
public long getElementCountInMemory() {
|
||||
|
@ -81,18 +83,30 @@ public class SecondLevelCacheStatisticsImpl extends CategorizedStatistics implem
|
|||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder()
|
||||
StringBuilder buf = new StringBuilder()
|
||||
.append("SecondLevelCacheStatistics")
|
||||
.append("[hitCount=").append(this.hitCount)
|
||||
.append(",missCount=").append(this.missCount)
|
||||
.append(",putCount=").append(this.putCount);
|
||||
//not sure if this would ever be null but wanted to be careful
|
||||
if (region != null) {
|
||||
builder.append(",elementCountInMemory=").append(this.getElementCountInMemory())
|
||||
buf.append(",elementCountInMemory=").append(this.getElementCountInMemory())
|
||||
.append(",elementCountOnDisk=").append(this.getElementCountOnDisk())
|
||||
.append(",sizeInMemory=").append(this.getSizeInMemory());
|
||||
}
|
||||
builder.append(']');
|
||||
return builder.toString();
|
||||
buf.append(']');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
void incrementHitCount() {
|
||||
hitCount.getAndIncrement();
|
||||
}
|
||||
|
||||
void incrementMissCount() {
|
||||
missCount.getAndIncrement();
|
||||
}
|
||||
|
||||
void incrementPutCount() {
|
||||
putCount.getAndIncrement();
|
||||
}
|
||||
}
|
|
@ -21,28 +21,34 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
package org.hibernate.stat.internal;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateLogger;
|
||||
import org.hibernate.cache.Region;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.hibernate.service.spi.Service;
|
||||
import org.hibernate.stat.CollectionStatistics;
|
||||
import org.hibernate.stat.EntityStatistics;
|
||||
import org.hibernate.stat.QueryStatistics;
|
||||
import org.hibernate.stat.SecondLevelCacheStatistics;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
* Implementation of {@link Statistics}, as well as {@link StatisticsImplementor}, based on the
|
||||
* {@link java.util.concurrent} package introduced in Java 5.
|
||||
* Implementation of {@link org.hibernate.stat.Statistics} based on the {@link java.util.concurrent} package.
|
||||
*
|
||||
* @author Alex Snaps
|
||||
*/
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public class ConcurrentStatisticsImpl implements Statistics, StatisticsImplementor {
|
||||
public class ConcurrentStatisticsImpl implements StatisticsImplementor, Service {
|
||||
|
||||
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class,
|
||||
ConcurrentStatisticsImpl.class.getName());
|
||||
private static final HibernateLogger LOG = Logger.getMessageLogger(HibernateLogger.class, ConcurrentStatisticsImpl.class.getName());
|
||||
|
||||
private SessionFactoryImplementor sessionFactory;
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
|
||||
* Copyright (c) 2008-2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Middleware LLC.
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
|
@ -20,12 +20,14 @@
|
|||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
package org.hibernate.stat.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.engine.SessionImplementor;
|
||||
import org.hibernate.stat.SessionStatistics;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
|
@ -27,8 +27,7 @@
|
|||
<head></head>
|
||||
<body>
|
||||
<p>
|
||||
This package exposes statistics about a running
|
||||
Hibernate instance to the application.
|
||||
This package exposes statistics about a running Hibernate instance to the application.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.stat;
|
||||
package org.hibernate.stat.spi;
|
||||
|
||||
import org.hibernate.stat.Statistics;
|
||||
|
||||
/**
|
||||
* Statistics SPI for the Hibernate core. This is essentially the "statistic collector" API, its the contract
|
||||
|
@ -30,7 +31,7 @@ package org.hibernate.stat;
|
|||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public interface StatisticsImplementor {
|
||||
public interface StatisticsImplementor extends Statistics {
|
||||
/**
|
||||
* Callback about a session being opened.
|
||||
*/
|
|
@ -30,8 +30,8 @@ import org.hibernate.engine.transaction.spi.TransactionEnvironment;
|
|||
import org.hibernate.engine.transaction.spi.TransactionFactory;
|
||||
import org.hibernate.service.jta.platform.spi.JtaPlatform;
|
||||
import org.hibernate.service.spi.ServiceRegistry;
|
||||
import org.hibernate.stat.ConcurrentStatisticsImpl;
|
||||
import org.hibernate.stat.StatisticsImplementor;
|
||||
import org.hibernate.stat.internal.ConcurrentStatisticsImpl;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
|
Loading…
Reference in New Issue