forked from mongodb/mongo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprofile_mongod.py
executable file
·124 lines (104 loc) · 3.26 KB
/
profile_mongod.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/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()