mirror of https://github.com/mongodb/mongo
125 lines
3.3 KiB
Python
Executable File
125 lines
3.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import json
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
from threading import Event
|
|
|
|
from profilerlib import CallMetrics
|
|
|
|
|
|
def get_profiler_stats(args):
|
|
command = [
|
|
"mongosh",
|
|
"--quiet",
|
|
"--eval",
|
|
"print(EJSON.stringify(db.runCommand({serverStatus: 1}).tracing_profiler))",
|
|
]
|
|
|
|
if args.username:
|
|
command.extend(["--username", args.username])
|
|
if args.password:
|
|
command.extend(["--password", args.password])
|
|
if args.host:
|
|
command.extend(["--host", args.host])
|
|
if args.port:
|
|
command.extend(["--port", args.port])
|
|
if args.tls:
|
|
command.append("--tls")
|
|
if args.tlsAllowInvalidCertificates:
|
|
command.append("--tlsAllowInvalidCertificates")
|
|
if args.tlsAllowInvalidHostnames:
|
|
command.append("--tlsAllowInvalidHostnames")
|
|
|
|
r = subprocess.check_output(command)
|
|
return json.loads(r)
|
|
|
|
|
|
def get_call_metrics(args):
|
|
return CallMetrics.from_json(get_profiler_stats(args))
|
|
|
|
|
|
def main():
|
|
stop_event = Event()
|
|
signal.signal(signal.SIGINT, lambda *_: stop_event.set())
|
|
|
|
parser = argparse.ArgumentParser(
|
|
usage="usage: %(prog)s [options]",
|
|
description="Collects a profiler data from mongod",
|
|
formatter_class=argparse.RawTextHelpFormatter,
|
|
epilog="Press CTRL-C to stop profiling",
|
|
)
|
|
parser.add_argument(
|
|
"-s",
|
|
"--sleep",
|
|
dest="sleep",
|
|
type=int,
|
|
help="profiles for given number of seconds, or indefinitely if not",
|
|
)
|
|
# The following are args that get passed through to mongosh
|
|
# See https://github.com/mongodb-js/mongosh?tab=readme-ov-file#cli-usage
|
|
parser.add_argument(
|
|
"-u",
|
|
"--username",
|
|
dest="username",
|
|
help="Username for authentication",
|
|
)
|
|
parser.add_argument(
|
|
"-p",
|
|
"--password",
|
|
dest="password",
|
|
help="Password for authentication",
|
|
)
|
|
parser.add_argument(
|
|
"--host",
|
|
dest="host",
|
|
help="Server to connect to",
|
|
)
|
|
parser.add_argument(
|
|
"--port",
|
|
dest="port",
|
|
help="Port to connect to",
|
|
)
|
|
parser.add_argument(
|
|
"--tls", dest="tls", action="store_true", help="Use TLS for all connections"
|
|
)
|
|
parser.add_argument(
|
|
"--tlsAllowInvalidCertificates",
|
|
dest="tlsAllowInvalidCertificates",
|
|
action="store_true",
|
|
help="Allow connections to servers with invalid certificates",
|
|
)
|
|
parser.add_argument(
|
|
"--tlsAllowInvalidHostnames",
|
|
dest="tlsAllowInvalidHostnames",
|
|
action="store_true",
|
|
help="Allow connections to servers with non-matching hostnames",
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
before_metrics = get_call_metrics(args)
|
|
|
|
sleep_sec = None
|
|
if args.sleep is not None:
|
|
sleep_sec = args.sleep
|
|
|
|
if sleep_sec is None:
|
|
print("Profiling indefinitely until interrupted...", file=sys.stderr)
|
|
else:
|
|
print(f"Profiling for {sleep_sec} seconds...", file=sys.stderr)
|
|
|
|
print("Press CTRL-C to stop profiling", file=sys.stderr)
|
|
stop_event.wait(sleep_sec)
|
|
|
|
after_metrics = get_call_metrics(args)
|
|
|
|
after_metrics.subtract(before_metrics)
|
|
print(after_metrics.to_json())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|