public final class DatabaseStatistics
extends java.lang.Object
The database is created in the server's current working directory, in a subdirectory named
perfdb
. This subdirectory will be created if it does not exist (and the server
process has the file system permissions to do so).
Statistics collection is disabled by default and is enabled via the directory, by setting path
persistence/collect-statistics
to true
. This will enable collection
for ALL auto-connect databases. Currently, there is no more granular setting than this.
Statistics currently are not collected for remotely connected databases (i.e., those connected
via the converted CONNECT Progress statement).
The statistics collected are for every HQL statement executed, and the second-level cache
statistics which Hibernate provides. For queries, we use both Hibernate's query statistics
(recorded by each SessionFactory
), and some simple use count statistics for each
query launched from a particular location in a converted application. This second bit allows
us to identify all the locations from which queries are executed in an application (the same
HQL can be executed from many places), whereas Hibernate's HQL statistics are global across an
application.
Note: Hibernate's timing statistics for query execution are based on millisecond precision (or as close to that as the JVM has implemented), so they can be somewhat misleading. That being said, the purpose of this class is to help identify query "hot spots" and evaluate second level cache performance, and this level of precision will have to do.
This perfdb
database can be accessed using the H2 console, which is available by
running:
java -jar <path_to_h2_jar_file>/h2.jarThis will open the default browser to a database connect page. The simplest way to connect to the
perfdb
database from this page is to use the embedded server option and
provide a URL as follows:
jdbc:h2:perfdb/perfdb;IFEXISTS=TRUE;ACCESS_MODE_DATA=rThis relative URL assumes you ran the
java
command above from the parent
directory of the perfdb
subdirectory. If not, you also can use an absolute URL:
jdbc:h2:/<path_to_perfdb>/perfdb;IFEXISTS=TRUE;ACCESS_MODE_DATA=rProvide the database user name and password configured in the application directory.
Refer to the H2 documentation (http://www.h2database.com) for additional information on how to use H2.
To delete previous performance statistics, simple delete the perfdb
subdirectory
(while the database is not open).
TODO: document perfdb
schema.
Modifier and Type | Class and Description |
---|---|
private static class |
DatabaseStatistics.Collector
Helper class which gathers local query statistics as the server is running, and which
collects global, Hibernate query and second level cache statistics as the server is
terminating.
|
private static class |
DatabaseStatistics.DatabaseHelper
Helper class to manage database operations while storing data to performance statistics
database.
|
private static class |
DatabaseStatistics.Location
Helper class which stores location information regarding the construction of a P2J query.
|
private static class |
DatabaseStatistics.QueryInfo
Helper class which stores information about the localized execution of HQL queries.
|
Modifier and Type | Field and Description |
---|---|
private static java.lang.String |
appPackagePrefix
Package root prefix stripped from application class names collected with statistics
|
private static int |
appPackagePrefixLength
Length of package root prefix, including trailing dot
|
private static java.lang.String |
COLLECT_STATS
Relative directory path for statistics collection flag
|
private java.util.Map<Database,DatabaseStatistics.Collector> |
collectors
Map of databases to statistics collectors
|
private static java.lang.String |
DB_PASS
Relative directory path for performance statistics database user password
|
private static java.lang.String |
DB_USER
Relative directory path for performance statistics database user name
|
private static java.util.logging.Logger |
log
Logger
|
private static java.lang.String |
PKGROOT
Relative directory path for application package root
|
private java.util.Map<P2JQuery,DatabaseStatistics.Location> |
queryCtorLocs
Transient map of query instances to information about where they were constructed
|
private static DatabaseStatistics |
singleton
Singleton instance of this class
|
Modifier | Constructor and Description |
---|---|
private |
DatabaseStatistics()
Private default constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
collectStatistics()
Collect statistics for all registered databases.
|
static DatabaseStatistics |
get()
Get the singleton instance of this class.
|
static boolean |
isEnabled()
Indicate whether statistics collection is enabled for this server instance.
|
(package private) void |
queryExecuted(P2JQuery query,
Database database,
java.lang.String hql)
This method should be invoked just after P2J query object has executed its query.
|
(package private) void |
registerDatabase(Database database,
org.hibernate.SessionFactory sessionFactory)
Register the given database for statistics collection.
|
(package private) void |
registerQuery(P2JQuery query)
Register the construction of a P2J query object by gathering application source code
location information for the query.
|
private static final java.util.logging.Logger log
private static final java.lang.String COLLECT_STATS
private static final java.lang.String DB_USER
private static final java.lang.String DB_PASS
private static final java.lang.String PKGROOT
private static final DatabaseStatistics singleton
private static final java.lang.String appPackagePrefix
private static final int appPackagePrefixLength
private final java.util.Map<Database,DatabaseStatistics.Collector> collectors
private final java.util.Map<P2JQuery,DatabaseStatistics.Location> queryCtorLocs
public static DatabaseStatistics get()
null
if statistics collection is disabled.public static boolean isEnabled()
true
if enabled, else false
.public void collectStatistics()
Note: this method is invoked during server termination. It appears logging and writing to stderr are not working properly at this point.
void registerDatabase(Database database, org.hibernate.SessionFactory sessionFactory)
database
- Database.sessionFactory
- Session factory which gathers Hibernate's statistics.void registerQuery(P2JQuery query)
At this point, we are very early in the query's construction and do not yet have information available as to the HQL which will be executed for this query, but we want to collect the exact location in the application source code at which the construction happened.
Note: this method is expensive, as it constructs a Throwable
on every call.
query
- P2J query object which is being constructed.void queryExecuted(P2JQuery query, Database database, java.lang.String hql)
query
- P2J query object which executed its query.database
- Database upon which the query was executed.hql
- Dialect-specific HQL query statement which was executed.