/**
* OpenKM, Open Document Management System (http://www.openkm.com)
* Copyright (c) 2006-2011 Paco Avila & Josep Llort
*
* No bytes were intentionally harmed during the development of this application.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package com.openkm.servlet.admin;
import java.io.IOException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.stat.CollectionStatistics;
import org.hibernate.stat.EntityStatistics;
import org.hibernate.stat.QueryStatistics;
import org.hibernate.stat.SecondLevelCacheStatistics;
import org.hibernate.stat.Statistics;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.openkm.dao.HibernateUtil;
import com.openkm.util.UserActivity;
import com.openkm.util.WebUtils;
/**
* Hibernate statistics servlet
*/
public class HibernateStatsServlet extends BaseServlet {
private static final long serialVersionUID = 1L;
private static Logger log = LoggerFactory.getLogger(HibernateStatsServlet.class);
static Map<String, QueryStatistics> queryStatistics = Collections.synchronizedMap(new TreeMap<String, QueryStatistics>(Collator.getInstance()));
static Map<String, EntityStatistics> entityStatistics = Collections.synchronizedMap(new TreeMap<String, EntityStatistics>(Collator.getInstance()));
static Map<String, CollectionStatistics> collectionStatistics = Collections.synchronizedMap(new TreeMap<String, CollectionStatistics>(Collator.getInstance()));
static Map<String, SecondLevelCacheStatistics> secondLevelCacheStatistics = Collections.synchronizedMap(new TreeMap<String, SecondLevelCacheStatistics>(Collator.getInstance()));
static List<Long> generalStatistics = Collections.synchronizedList(new ArrayList<Long>(18));
static {
for (int i=0; i<9; i++) {
generalStatistics.add(new Long(-1));
}
}
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException {
String method = request.getMethod();
if (checkMultipleInstancesAccess(request, response)) {
if (method.equals(METHOD_GET)) {
doGet(request, response);
} else if (method.equals(METHOD_POST)) {
doPost(request, response);
}
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String action = WebUtils.getString(request, "action");
updateSessionManager(request);
try {
if (action.equals("activate")) {
activate(request, response);
} else if (action.equals("deactivate")) {
deactivate(request, response);
} else if (action.equals("clear")) {
clear(request, response);
}
view(request, response);
} catch (Exception e) {
log.error(e.getMessage(), e);
sendErrorRedirect(request,response, e);
}
}
/**
* Activate stats
*/
private void activate(HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException {
Statistics stats = HibernateUtil.getSessionFactory().getStatistics();
if (!stats.isStatisticsEnabled()) {
stats.setStatisticsEnabled(true);
}
}
/**
* Deactivate stats
*/
private void deactivate(HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException {
Statistics stats = HibernateUtil.getSessionFactory().getStatistics();
if (stats.isStatisticsEnabled()) {
stats.setStatisticsEnabled(false);
}
}
/**
* Clear stats
*/
private void clear(HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException {
HibernateUtil.getSessionFactory().getStatistics().clear();
generalStatistics.set(0, new Long(0));
generalStatistics.set(1, new Long(0));
generalStatistics.set(2, new Long(0));
generalStatistics.set(3, new Long(0));
generalStatistics.set(4, new Long(0));
generalStatistics.set(5, new Long(0));
generalStatistics.set(6, new Long(0));
generalStatistics.set(7, new Long(0));
generalStatistics.set(8, new Long(0));
queryStatistics.clear();
entityStatistics.clear();
collectionStatistics.clear();
secondLevelCacheStatistics.clear();
}
/**
* View log
*/
private void view(HttpServletRequest request, HttpServletResponse response) throws IOException,
ServletException {
log.debug("view({}, {})", request, response);
refresh();
// Query Statistics
List<Map<String, String>> qStats = new ArrayList<Map<String,String>>();
for (String query : queryStatistics.keySet()) {
QueryStatistics queryStats = queryStatistics.get(query);
Map<String, String> stat = new HashMap<String, String>();
stat.put("query", query);
//stat.put("tquery", HibernateUtil.toSql(query));
stat.put("executionCount", Long.toString(queryStats.getExecutionCount()));
stat.put("executionRowCount", Long.toString(queryStats.getExecutionRowCount()));
stat.put("executionMaxTime", Long.toString(queryStats.getExecutionMaxTime()));
stat.put("executionMinTime", Long.toString(queryStats.getExecutionMinTime()));
stat.put("executionAvgTime", Long.toString(queryStats.getExecutionAvgTime()));
stat.put("executionTotalTime", Long.toString(queryStats.getExecutionAvgTime() * queryStats.getExecutionCount()));
stat.put("cacheHitCount", Long.toString(queryStats.getCacheHitCount()));
stat.put("cacheMissCount", Long.toString(queryStats.getCacheMissCount()));
stat.put("cachePutCount", Long.toString(queryStats.getCachePutCount()));
qStats.add(stat);
}
// Entity Statistics
List<Map<String, String>> eStats = new ArrayList<Map<String,String>>();
for (String entity : entityStatistics.keySet()) {
EntityStatistics entityStats = entityStatistics.get(entity);
Map<String, String> stat = new HashMap<String, String>();
stat.put("entity", entity);
stat.put("loadCount", Long.toString(entityStats.getLoadCount()));
stat.put("fetchCount", Long.toString(entityStats.getFetchCount()));
stat.put("insertCount", Long.toString(entityStats.getInsertCount()));
stat.put("updateCount", Long.toString(entityStats.getUpdateCount()));
stat.put("deleteCount", Long.toString(entityStats.getDeleteCount()));
stat.put("optimisticFailureCount", Long.toString(entityStats.getOptimisticFailureCount()));
eStats.add(stat);
}
// Collection Statistics
List<Map<String, String>> cStats = new ArrayList<Map<String,String>>();
for (String collection : collectionStatistics.keySet()) {
CollectionStatistics collectionStats = collectionStatistics.get(collection);
Map<String, String> stat = new HashMap<String, String>();
stat.put("collection", collection);
stat.put("loadCount", Long.toString(collectionStats.getLoadCount()));
stat.put("fetchCount", Long.toString(collectionStats.getFetchCount()));
stat.put("updateCount", Long.toString(collectionStats.getUpdateCount()));
stat.put("recreateCount", Long.toString(collectionStats.getRecreateCount()));
stat.put("removeCount", Long.toString(collectionStats.getRemoveCount()));
cStats.add(stat);
}
// 2nd Level Cache Statistics
long totalSizeInMemory = 0;
List<Map<String, String>> slcStats = new ArrayList<Map<String,String>>();
for (String cache : secondLevelCacheStatistics.keySet()) {
SecondLevelCacheStatistics cacheStats = secondLevelCacheStatistics.get(cache);
totalSizeInMemory += cacheStats.getSizeInMemory();
Map<String, String> stat = new HashMap<String, String>();
stat.put("cache", cache);
stat.put("putCount", Long.toString(cacheStats.getPutCount()));
stat.put("hitCount", Long.toString(cacheStats.getHitCount()));
stat.put("missCount", Long.toString(cacheStats.getMissCount()));
stat.put("elementCountInMemory", Long.toString(cacheStats.getElementCountInMemory()));
stat.put("sizeInMemory", Long.toString(cacheStats.getSizeInMemory()));
stat.put("elementCountOnDisk", Long.toString(cacheStats.getElementCountOnDisk()));
slcStats.add(stat);
}
ServletContext sc = getServletContext();
sc.setAttribute("generalStats", generalStatistics);
sc.setAttribute("queryStats", qStats);
sc.setAttribute("entityStats", eStats);
sc.setAttribute("collectionStats", cStats);
sc.setAttribute("secondLevelCacheStats", slcStats);
sc.setAttribute("totalSizeInMemory", totalSizeInMemory);
sc.setAttribute("statsEnabled", HibernateUtil.getSessionFactory().getStatistics().isStatisticsEnabled());
sc.getRequestDispatcher("/admin/hibernate_stats.jsp").forward(request, response);
// Activity log
UserActivity.log(request.getRemoteUser(), "ADMIN_HIBERNATE_STATS", null, null);
log.debug("view: void");
}
/**
* Refresh stats
*/
private synchronized void refresh() {
Statistics statistics = HibernateUtil.getSessionFactory().getStatistics();
generalStatistics.set(0, statistics.getConnectCount());
generalStatistics.set(1, statistics.getFlushCount());
generalStatistics.set(2, statistics.getPrepareStatementCount());
generalStatistics.set(3, statistics.getCloseStatementCount());
generalStatistics.set(4, statistics.getSessionCloseCount());
generalStatistics.set(5, statistics.getSessionOpenCount());
generalStatistics.set(6, statistics.getTransactionCount());
generalStatistics.set(7, statistics.getSuccessfulTransactionCount());
generalStatistics.set(8, statistics.getOptimisticFailureCount());
queryStatistics.clear();
String [] names = statistics.getQueries();
if (names != null && names.length > 0) {
for (int i=0; i<names.length; i++) {
queryStatistics.put(names[i], statistics.getQueryStatistics(names[i]));
}
}
entityStatistics.clear();
names = statistics.getEntityNames();
if (names != null && names.length > 0) {
for (int i=0; i<names.length; i++) {
entityStatistics.put(names[i], statistics.getEntityStatistics(names[i]));
}
}
collectionStatistics.clear();
names = statistics.getCollectionRoleNames();
if (names != null && names.length > 0) {
for (int i=0; i<names.length; i++) {
collectionStatistics.put(names[i], statistics.getCollectionStatistics(names[i]));
}
}
secondLevelCacheStatistics.clear();
names = statistics.getSecondLevelCacheRegionNames();
if (names != null && names.length > 0) {
for (int i=0; i<names.length; i++) {
secondLevelCacheStatistics.put(names[i], statistics.getSecondLevelCacheStatistics(names[i]));
}
}
}
}