diff --git a/mongodbtools/collection_stats.py b/mongodbtools/collection_stats.py index 4e03464..8bade4b 100755 --- a/mongodbtools/collection_stats.py +++ b/mongodbtools/collection_stats.py @@ -7,9 +7,18 @@ from prettytable import PrettyTable import psutil -from pymongo import Connection +from socket import getfqdn from pymongo import ReadPreference from optparse import OptionParser +from distutils.version import StrictVersion +import pymongo + +HAS_PYMONGO3 = bool(StrictVersion(pymongo.version) >= StrictVersion('3.0')) + +if HAS_PYMONGO3: + from pymongo import MongoClient +else: + from pymongo import Connection as MongoClient # pylint: disable=E0611 def compute_signature(index): signature = index["ns"] @@ -18,7 +27,7 @@ def compute_signature(index): return signature def get_collection_stats(database, collection): - print "Checking DB: %s" % collection.full_name + print("Checking DB: %s" % collection.full_name) return database.command("collstats", collection.name) def get_cli_options(): @@ -50,18 +59,34 @@ def get_cli_options(): default="", metavar="PASSWORD", help="Admin password if authentication is enabled") + parser.add_option("--ssl-cert", + dest="ssl_certfile", + default=None, + metavar="CERTIFICATE", + help="SSL Certificate to use is SSL is enabled (only with pymongo >= 3)") + parser.add_option("--ssl-ca-certs", + dest="ssl_ca_certs", + default=None, + metavar="CA", + help="SSL Certificate of CA for certificate validation if SSL is enabled (only with pymongo >= 3)") (options, args) = parser.parse_args() return options -def get_connection(host, port, username, password): +def get_connection(host, port, username, password, ssl_certfile=None, ssl_ca_certs=None): userPass = "" if username and password: userPass = username + ":" + password + "@" mongoURI = "mongodb://" + userPass + host + ":" + str(port) - return Connection(host=mongoURI, read_preference=ReadPreference.SECONDARY) + + conn_kwargs = dict(host=mongoURI, read_preference=ReadPreference.SECONDARY) + + if HAS_PYMONGO3: + conn_kwargs.update(dict(ssl_certfile=ssl_certfile, ssl_ca_certs=ssl_ca_certs)) + + return MongoClient(**conn_kwargs) # From http://www.5dollarwhitebox.org/drupal/node/84 def convert_bytes(bytes): @@ -83,7 +108,10 @@ def convert_bytes(bytes): size = '%.2fb' % bytes return size -def main(options): +def main(options=None): + if options is None: + options = get_cli_options() + summary_stats = { "count" : 0, "size" : 0, @@ -92,7 +120,8 @@ def main(options): } all_stats = [] - connection = get_connection(options.host, options.port, options.user, options.password) + connection = get_connection(options.host, options.port, options.user, options.password, + options.ssl_certfile, options.ssl_ca_certs) all_db_stats = {} @@ -145,18 +174,18 @@ def main(options): ]) print - print x.get_string(sortby="% Size") - print "Total Documents:", summary_stats["count"] - print "Total Data Size:", convert_bytes(summary_stats["size"]) - print "Total Index Size:", convert_bytes(summary_stats["indexSize"]) - print "Total Storage Size:", convert_bytes(summary_stats["storageSize"]) + print(x.get_string(sortby="% Size")) + print("Total Documents: %s" % summary_stats["count"]) + print("Total Data Size: %s" % convert_bytes(summary_stats["size"])) + print("Total Index Size: %s" % convert_bytes(summary_stats["indexSize"])) + print("Total Storage Size: %s" % convert_bytes(summary_stats["storageSize"])) # this is only meaningful if we're running the script on localhost - if options.host == "localhost": + if options.host == "localhost" or options.host == getfqdn(): ram_headroom = psutil.phymem_usage()[0] - summary_stats["indexSize"] - print "RAM Headroom:", convert_bytes(ram_headroom) - print "RAM Used: %s (%s%%)" % (convert_bytes(psutil.phymem_usage()[1]), psutil.phymem_usage()[3]) - print "Available RAM Headroom:", convert_bytes((100 - psutil.phymem_usage()[3]) / 100 * ram_headroom) + print("RAM Headroom: %s" % convert_bytes(ram_headroom)) + print("RAM Used: %s (%s%%)" % (convert_bytes(psutil.phymem_usage()[1]), psutil.phymem_usage()[3])) + print("Available RAM Headroom: %s" % convert_bytes((100 - psutil.phymem_usage()[3]) / 100 * ram_headroom)) if __name__ == "__main__": options = get_cli_options() diff --git a/mongodbtools/index_stats.py b/mongodbtools/index_stats.py index fd1313d..11ccfdc 100755 --- a/mongodbtools/index_stats.py +++ b/mongodbtools/index_stats.py @@ -7,9 +7,18 @@ from prettytable import PrettyTable import psutil -from pymongo import Connection +from socket import getfqdn from pymongo import ReadPreference from optparse import OptionParser +from distutils.version import StrictVersion +import pymongo + +HAS_PYMONGO3 = bool(StrictVersion(pymongo.version) >= StrictVersion('3.0')) + +if HAS_PYMONGO3: + from pymongo import MongoClient +else: + from pymongo import Connection as MongoClient # pylint: disable=E0611 def compute_signature(index): signature = index["ns"] @@ -18,7 +27,7 @@ def compute_signature(index): return signature def get_collection_stats(database, collection): - print "Checking DB: %s" % collection.full_name + print("Checking DB: %s" % collection.full_name) return database.command("collstats", collection.name) # From http://www.5dollarwhitebox.org/drupal/node/84 @@ -70,20 +79,39 @@ def get_cli_options(): default="", metavar="PASSWORD", help="Admin password if authentication is enabled") + parser.add_option("--ssl-cert", + dest="ssl_certfile", + default=None, + metavar="CERTIFICATE", + help="SSL Certificate to use is SSL is enabled") + parser.add_option("--ssl-ca-certs", + dest="ssl_ca_certs", + default=None, + metavar="CA", + help="SSL Certificate of CA for certificate validation if SSL is enabled") (options, args) = parser.parse_args() return options -def get_connection(host, port, username, password): +def get_connection(host, port, username, password, ssl_certfile=None, ssl_ca_certs=None): userPass = "" if username and password: userPass = username + ":" + password + "@" mongoURI = "mongodb://" + userPass + host + ":" + str(port) - return Connection(host=mongoURI, read_preference=ReadPreference.SECONDARY) -def main(options): + conn_kwargs = dict(host=mongoURI, read_preference=ReadPreference.SECONDARY) + + if HAS_PYMONGO3: + conn_kwargs.update(dict(ssl_certfile=ssl_certfile, ssl_ca_certs=ssl_ca_certs)) + + return MongoClient(**conn_kwargs) + +def main(options=None): + if options is None: + options = get_cli_options() + summary_stats = { "count" : 0, "size" : 0, @@ -91,7 +119,8 @@ def main(options): } all_stats = [] - connection = get_connection(options.host, options.port, options.user, options.password) + connection = get_connection(options.host, options.port, options.user, options.password, + options.ssl_certfile, options.ssl_ca_certs) all_db_stats = {} @@ -141,11 +170,11 @@ def main(options): x.add_row(row) - print "Index Overview" - print x.get_string(sortby="Collection") + print("Index Overview") + print(x.get_string(sortby="Collection")) print - print "Top 5 Largest Indexes" + print("Top 5 Largest Indexes") x = PrettyTable(["Collection", "Index","% Size", "Index Size"]) x.align["Collection"] = "l" x.align["Index"] = "l" @@ -156,19 +185,19 @@ def main(options): top_five_indexes = sorted(index_size_mapping.keys(), reverse=True)[0:5] for size in top_five_indexes: x.add_row(index_size_mapping.get(size)) - print x + print(x) print - print "Total Documents:", summary_stats["count"] - print "Total Data Size:", convert_bytes(summary_stats["size"]) - print "Total Index Size:", convert_bytes(summary_stats["indexSize"]) + print("Total Documents: %s" % summary_stats["count"]) + print("Total Data Size: %s" % convert_bytes(summary_stats["size"])) + print("Total Index Size: %s" % convert_bytes(summary_stats["indexSize"])) # this is only meaningful if we're running the script on localhost - if options.host == "localhost": + if options.host == "localhost" or options.host == getfqdn(): ram_headroom = psutil.phymem_usage()[0] - summary_stats["indexSize"] - print "RAM Headroom:", convert_bytes(ram_headroom) - print "RAM Used: %s (%s%%)" % (convert_bytes(psutil.phymem_usage()[1]), psutil.phymem_usage()[3]) - print "Available RAM Headroom:", convert_bytes((100 - psutil.phymem_usage()[3]) / 100 * ram_headroom) + print("RAM Headroom: %s" % convert_bytes(ram_headroom)) + print("RAM Used: %s (%s%%)" % (convert_bytes(psutil.phymem_usage()[1]), psutil.phymem_usage()[3])) + print("Available RAM Headroom: %s" % convert_bytes((100 - psutil.phymem_usage()[3]) / 100 * ram_headroom)) if __name__ == "__main__": options = get_cli_options() diff --git a/mongodbtools/redundant_indexes.py b/mongodbtools/redundant_indexes.py index 12b202e..fa5e843 100755 --- a/mongodbtools/redundant_indexes.py +++ b/mongodbtools/redundant_indexes.py @@ -6,10 +6,17 @@ with just fields {field1:1}, the latter index is not needed since the first index already indexes the necessary fields. """ -from pymongo import Connection from pymongo import ReadPreference from optparse import OptionParser +from distutils.version import StrictVersion +import pymongo +HAS_PYMONGO3 = bool(StrictVersion(pymongo.version) >= StrictVersion('3.0')) + +if HAS_PYMONGO3: + from pymongo import MongoClient +else: + from pymongo import Connection as MongoClient # pylint: disable=E0611 def get_cli_options(): parser = OptionParser(usage="usage: python %prog [options]", @@ -40,21 +47,41 @@ def get_cli_options(): default="", metavar="PASSWORD", help="Admin password if authentication is enabled") + parser.add_option("--ssl-cert", + dest="ssl_certfile", + default=None, + metavar="CERTIFICATE", + help="SSL Certificate to use is SSL is enabled (only with pymongo >= 3)") + parser.add_option("--ssl-ca-certs", + dest="ssl_ca_certs", + default=None, + metavar="CA", + help="SSL Certificate of CA for certificate validation if SSL is enabled (only with pymongo >= 3)") (options, args) = parser.parse_args() return options -def get_connection(host, port, username, password): +def get_connection(host, port, username, password, ssl_certfile=None, ssl_ca_certs=None): userPass = "" if username and password: userPass = username + ":" + password + "@" mongoURI = "mongodb://" + userPass + host + ":" + str(port) - return Connection(host=mongoURI, read_preference=ReadPreference.SECONDARY) -def main(options): - connection = get_connection(options.host, options.port, options.user, options.password) + conn_kwargs = dict(host=mongoURI, read_preference=ReadPreference.SECONDARY) + + if HAS_PYMONGO3: + conn_kwargs.update(dict(ssl_certfile=ssl_certfile, ssl_ca_certs=ssl_ca_certs)) + + return MongoClient(**conn_kwargs) + +def main(options=None): + if options is None: + options = get_cli_options() + + connection = get_connection(options.host, options.port, options.user, options.password, + options.ssl_certfile, options.ssl_ca_certs) def compute_signature(index): signature = index["ns"] @@ -66,7 +93,7 @@ def compute_signature(index): return signature def report_redundant_indexes(current_db): - print "Checking DB: %s" % current_db.name + print("Checking DB: %s" % current_db.name) indexes = current_db.system.indexes.find() index_map = {} for index in indexes: @@ -78,11 +105,11 @@ def report_redundant_indexes(current_db): if signature == other_sig: continue if other_sig.startswith(signature): - print "Index %s[%s] may be redundant with %s[%s]" % ( + print ("Index %s[%s] may be redundant with %s[%s]" % ( index_map[signature]["ns"], index_map[signature]["name"], index_map[other_sig]["ns"], - index_map[other_sig]["name"]) + index_map[other_sig]["name"])) databases= [] if options.database: diff --git a/requirements.txt b/requirements.txt index c880503..237758a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -pymongo==2.1 +pymongo>=2.1 PrettyTable==0.7.1 psutil==0.3.0 mongoengine==0.5.0