/* * eXist Open Source Native XML Database * Copyright (C) 2001-07 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * $Id: Database.java 6177 2007-07-08 14:42:37Z wolfgang_m $ */ package org.exist.management.impl; import java.io.StringWriter; import java.util.Map; import java.util.Optional; import javax.management.openmbean.*; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; public class Database implements DatabaseMXBean { private static final String[] itemNames = { "owner", "referenceCount", "stack", "stackAcquired"}; private static final String[] itemDescriptions = { "Name of the thread owning the broker", "Number of references held by the thread", "Stack trace", "Broker acquired" }; private static final String[] indexNames = {"owner"}; private final BrokerPool pool; public Database(BrokerPool pool) { this.pool = pool; } @Override public String getInstanceId() { return pool.getId(); } @Override public int getMaxBrokers() { return pool.getMax(); } @Override public int getAvailableBrokers() { return pool.available(); } @Override public int getActiveBrokers() { return pool.countActiveBrokers(); } @Override public int getTotalBrokers() { return pool.total(); } @Override public TabularData getActiveBrokersMap() { final OpenType<?>[] itemTypes = { SimpleType.STRING, SimpleType.INTEGER, SimpleType.STRING, SimpleType.STRING }; try { final CompositeType infoType = new CompositeType("brokerInfo", "Provides information on a broker instance.", itemNames, itemDescriptions, itemTypes); final TabularType tabularType = new TabularType("activeBrokers", "Lists all threads currently using a broker instance", infoType, indexNames); final TabularDataSupport data = new TabularDataSupport(tabularType); for (final Map.Entry<Thread, DBBroker> entry : pool.getActiveBrokers().entrySet()) { final Thread thread = entry.getKey(); final DBBroker broker = entry.getValue(); final String trace = printStackTrace(thread); final String watchdogTrace = pool.getWatchdog().map(wd -> wd.get(broker)).orElse(null); final Object[] itemValues = { thread.getName(), broker.getReferenceCount(), trace, watchdogTrace }; data.put(new CompositeDataSupport(infoType, itemNames, itemValues)); } return data; } catch (final OpenDataException e) { e.printStackTrace(); return null; } } @Override public long getReservedMem() { return pool.getReservedMem(); } @Override public long getCacheMem() { return pool.getCacheManager().getTotalMem(); } @Override public long getCollectionCacheMem() { return pool.getCollectionCacheMgr().getMaxTotal(); } @Override public long getUptime() { return System.currentTimeMillis() - pool.getStartupTime().getTimeInMillis(); } @Override public String getExistHome() { return pool.getConfiguration().getExistHome().map(p -> p.toAbsolutePath().toString()).orElse(null); } public String printStackTrace(Thread thread) { final StackTraceElement[] stackElements = thread.getStackTrace(); final StringWriter writer = new StringWriter(); final int showItems = stackElements.length > 20 ? 20 : stackElements.length; for (int i = 0; i < showItems; i++) { writer.append(stackElements[i].toString()).append('\n'); } return writer.toString(); } }