All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.mongodb.tools.ConnectionPoolStat Maven / Gradle / Ivy

Go to download

The MongoDB Java Driver uber-artifact, containing mongodb-driver, mongodb-driver-core, and bson

There is a newer version: 3.1.0
Show newest version
/*
 * Copyright (c) 2008-2014 MongoDB, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mongodb.tools;

import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.JMException;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.openmbean.CompositeData;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.management.ManagementFactory;
import java.util.Set;

/**
 * A simple class that formats Mongo Java driver connection pool statistics in an easily-accessible JSON format.
 * It can be used to get statistics on connection pool in the same VM by using the no-args constructor, or in any
 * VM by using the constructor that takes an MBeanServerConnection.
 * 

* This class also exposes a command line interface modeled after mongostat. For usage, run: *

   java -cp mongo.jar com.mongodb.util.tools.ConnectionPoolStat --help}
* * @mongodb.driver.manual reference/mongostat mongostat * @deprecated This class will be removed in 3.x versions of the driver, * so please remove it from your compile time dependencies. */ @Deprecated public class ConnectionPoolStat { /** * Use the given MBean server connection to access statistics for connection pools. * * @param mBeanConnection the MBean server to connect to */ public ConnectionPoolStat(MBeanServerConnection mBeanConnection) { this.mBeanConnection = mBeanConnection; } /** * Use the platform MBean server. This is useful if you want to access statistics * for connection pools in the same virtual machine. * * @see java.lang.management.ManagementFactory#getPlatformMBeanServer() */ public ConnectionPoolStat() { this.mBeanConnection = ManagementFactory.getPlatformMBeanServer(); } /** * Gets the statistics for all Mongo connection pools registered with the MBean server used * by this instance. The format will always be JSON, but the specific JSON fields may change in a * future release. An example of the output, which should not be taken as a specification: * *
   { pools : [
     { objectName: 'com.mongodb:type=ConnectionPool,host=localhost/127.0.0.1,port=27018,instance=1',
       host: 'localhost', port: 27018, maxSize: 10, total: 10, inUse: 3,
       inUseConnections: [
         { namespace: 'FindContention.test', opCode: 'OP_QUERY', query: { }, numDocuments: 1, threadName: 'pool-2-thread-19', durationMS: 843, localPort: 64062 },
         { namespace: 'FindContention.test', opCode: 'OP_QUERY', query: { }, numDocuments: 1, threadName: 'pool-2-thread-1', durationMS: 4331, localPort: 64095 },
         { namespace: 'FindContention.test', opCode: 'OP_QUERY', query: { }, numDocuments: 1, threadName: 'pool-2-thread-16', durationMS: 4343, localPort: 64087 }
       ]
     },
     { objectName: 'com.mongodb:type=ConnectionPool,host=localhost/127.0.0.1,port=27017,instance=1',
       host: 'localhost', port: 27017, maxSize: 10, total: 10, inUse: 2,
       inUseConnections: [
         { namespace: 'FindContention.test', opCode: 'OP_QUERY', query: { }, numDocuments: 1, threadName: 'pool-2-thread-5', durationMS: 920, localPort: 64093 },
         { namespace: 'FindContention.test', opCode: 'OP_QUERY', query: { }, numDocuments: 1, threadName: 'pool-2-thread-11', durationMS: 1468, localPort: 64068 },
       ]
     }
    ]
   }
* * @return JSON-formatted stats for all connection pools registered in JMX * @throws JMException for any JMX-related exceptions * @throws IOException for any I/O exceptions */ public String getStats() throws JMException, IOException { CharArrayWriter charArrayWriter = new CharArrayWriter(); PrintWriter printWriter = new PrintWriter(charArrayWriter); print(printWriter); return charArrayWriter.toString(); } /** * Command line interface for displaying connection pool stats. In order to connect to a remote JMX server to * get these stats, currently you must set com.sun.management.jmxremote.port system property on the remote server * and specify that port using the --port argument. * * @param args program arguments * @throws Exception JMX-related exceptions * @see ConnectionPoolStat#printUsage() */ public static void main(String[] args) throws Exception { String host = "localhost"; int port = -1; long rowCount = 0; int sleepTime = 1000; int pos = 0; for (; pos < args.length; pos++) { if (args[pos].equals("--help")) { printUsage(); System.exit(0); } else if (args[pos].equals("--host") || args[pos].equals("-h")) { host = args[++pos]; } else if (args[pos].equals("--port")) { port = getIntegerArg(args[++pos], "--port"); } else if (args[pos].equals("--rowcount") || args[pos].equals("-n")) { rowCount = getIntegerArg(args[++pos], "--rowCount"); } else if (args[pos].startsWith("-")) { printErrorAndUsageAndExit("unknown option " + args[pos]); } else { sleepTime = getIntegerArg(args[pos++], "sleep time") * 1000; break; } } if (pos != args.length) { printErrorAndUsageAndExit("too many positional options"); } if (port == -1 && !host.contains(":")) { printErrorAndUsageAndExit("port is required"); } String hostAndPort = (port != -1) ? host + ":" + port : host; if (rowCount == 0) { rowCount = Long.MAX_VALUE; } JMXServiceURL u = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + hostAndPort + "/jmxrmi"); JMXConnector connector = JMXConnectorFactory.connect(u); MBeanServerConnection mBeanConnection = connector.getMBeanServerConnection(); try { ConnectionPoolStat printer = new ConnectionPoolStat(mBeanConnection); for (int i = 0; i < rowCount; i++) { System.out.println(printer.getStats()); if (i != rowCount - 1) { Thread.sleep(sleepTime); } } } finally { connector.close(); } } private static int getIntegerArg(String arg, String argName) { try { return Integer.parseInt(arg); } catch (NumberFormatException e) { printErrorAndUsageAndExit(argName + " arg must be an integer"); } throw new IllegalStateException(); } private static void printErrorAndUsageAndExit(final String error) { System.err.println("ERROR: " + error); System.out.println(); printUsage(); System.exit(1); } private static void printUsage() { System.out.println("View live MongoDB connection pool statistics from a remote JMX server."); System.out.println(); System.out.println("usage: java com.mongodb.tools.ConnectionPoolStat [options] [sleep time"); System.out.println("sleep time: time to wait (in seconds) between calls. Defaults to 1"); System.out.println("options:"); System.out.println(" --help produce help message"); System.out.println(" --port arg JMX remote port. Required. Can also use --host hostname:port"); System.out.println(" -h [ --host ] arg JMX remote host. Defaults to localhost"); System.out.println(" -n [ --rowcount ] arg number of times to print stats (0 for indefinite)"); System.out.println(); System.out.println("Fields"); System.out.println(" objectName - name of the JMX bean for this connection pool"); System.out.println(" host - host of the mongod/mongos server"); System.out.println(" port - port of the mongod/mongos server"); System.out.println(" maxSize - max # of connections allowed"); System.out.println(" total - # of connections allocated"); System.out.println(" inUse - # of connections in use"); System.out.println(" inUseConnections - list of all in use connections"); System.out.println(" inUseConnections.namespace - namespace on which connection is operating"); System.out.println(" inUseConnections.opCode - operation connection is executing"); System.out.println(" inUseConnections.query - query the connection is executing (for query/update/remove)"); System.out.println(" inUseConnections.numDocuments - # of documents in the message (mostly relevant for batch inserts)"); System.out.println(" inUseConnections.threadName - name of thread on which connection is executing"); System.out.println(" inUseConnections.durationMS - duration that the operation has been executing so far"); System.out.println(" inUseConnections.localPort - local port of the connection"); } private void print(PrintWriter pw) throws JMException, IOException { Set beanSet = mBeanConnection.queryNames(new ObjectName("com.mongodb:type=ConnectionPool,*"), null); pw.println("{ pools : ["); int i = 0; for (ObjectName objectName : beanSet) { pw.print(" { "); printAttribute("ObjectName", objectName.toString(), pw); pw.println(); pw.print(" "); printAttribute("Host", objectName, pw); printAttribute("Port", objectName, pw); printAttribute("MaxSize", objectName, pw); printStatistics(pw, objectName); pw.println(" }" + (i == beanSet.size() - 1 ? "" : ",")); i++; } pw.println(" ]"); pw.println("}"); } private void printStatistics(final PrintWriter pw, final ObjectName objectName) throws InstanceNotFoundException, IOException, ReflectionException, AttributeNotFoundException, MBeanException { String key = "Statistics"; CompositeData statistics = (CompositeData) mBeanConnection.getAttribute(objectName, key); printSimpleStatistics(pw, statistics); printInUseConnections(statistics, pw); } private void printSimpleStatistics(final PrintWriter pw, final CompositeData statistics) throws InstanceNotFoundException, IOException, ReflectionException, AttributeNotFoundException, MBeanException { printCompositeDataAttribute("total", statistics, pw); printCompositeDataAttribute("inUse", statistics, pw); pw.println(); } private void printInUseConnections(final CompositeData statistics, final PrintWriter pw) throws InstanceNotFoundException, IOException, ReflectionException, AttributeNotFoundException, MBeanException { String key = "inUseConnections"; CompositeData[] compositeDataArray = (CompositeData[]) statistics.get(key); pw.println(" " + getKeyString(key) + ": ["); for (int i = 0; i < compositeDataArray.length; i++) { CompositeData compositeData = compositeDataArray[i]; pw.print(" { "); printCompositeDataAttribute("namespace", compositeData, pw); printCompositeDataAttribute("opCode", compositeData, pw); printCompositeDataAttribute("query", compositeData, pw, StringType.JSON); printCompositeDataAttribute("numDocuments", compositeData, pw); printCompositeDataAttribute("threadName", compositeData, pw); printCompositeDataAttribute("durationMS", compositeData, pw); printCompositeDataAttribute("localPort", compositeData, pw, Position.LAST); pw.println(" }" + (i == compositeDataArray.length -1 ? "" : ", ")); } pw.println(" ]"); } private void printCompositeDataAttribute(String key, final CompositeData compositeData, final PrintWriter pw) { printCompositeDataAttribute(key, compositeData, pw, Position.REGULAR); } private void printCompositeDataAttribute(String key, final CompositeData compositeData, final PrintWriter pw, Position position) { printCompositeDataAttribute(key, compositeData, pw, position, StringType.REGULAR); } private void printCompositeDataAttribute(final String key, final CompositeData compositeData, final PrintWriter pw, final StringType stringType) { printCompositeDataAttribute(key, compositeData, pw, Position.REGULAR, stringType); } private void printCompositeDataAttribute(String key, final CompositeData compositeData, final PrintWriter pw, Position position, StringType stringType) { printAttribute(key, compositeData.get(key), pw, position, stringType); } private void printAttribute(final String key, final ObjectName objectName, final PrintWriter pw) throws InstanceNotFoundException, IOException, ReflectionException, AttributeNotFoundException, MBeanException { printAttribute(key, mBeanConnection.getAttribute(objectName, key), pw); } private void printAttribute(final String key, final Object value, final PrintWriter pw) { printAttribute(key, value, pw, Position.REGULAR, StringType.REGULAR); } private void printAttribute(final String key, final Object value, final PrintWriter pw, Position position, StringType stringType) { if (value != null ) { pw.print(getKeyString(key) + ": " + getValueString(value, stringType) + (position == Position.LAST ? "" : ", ")); } } private String getKeyString(final String key) { return Character.toLowerCase(key.charAt(0)) + key.substring(1); } private String getValueString(final Object value, final StringType stringType) { if (value instanceof String && stringType == StringType.REGULAR) { return "" + "'" + value + "'"; } return value.toString(); } enum StringType { REGULAR, JSON } enum Position { REGULAR, LAST} private final MBeanServerConnection mBeanConnection; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy