Skip to content

Commit 4125f53

Browse files
scripts: add set log level script
1 parent a109ad6 commit 4125f53

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed

scripts/set_log_level.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import argparse
2+
import subprocess
3+
import sys
4+
import time
5+
from typing import List
6+
7+
import requests
8+
import signal
9+
import socket
10+
11+
12+
def parse_args(args: List[str]) -> argparse.Namespace:
13+
parser = argparse.ArgumentParser(description="Set the log level for a crate")
14+
parser.add_argument(
15+
"--crate_name", type=str, help="The name of the crate to set the log level for"
16+
)
17+
parser.add_argument("--log_level", type=str, help="The log level to set for the crate")
18+
parser.add_argument(
19+
"--pod_name",
20+
type=str,
21+
default="",
22+
help="Optional Kubernetes pod name to port-forward to",
23+
)
24+
25+
parser.add_argument(
26+
"--local_port",
27+
type=int,
28+
default=8082,
29+
help="Local port to bind the port-forward to (defaults to 8082)",
30+
)
31+
32+
parser.add_argument(
33+
"--monitoring_port",
34+
type=int,
35+
default=8082,
36+
help="Monitoring port exposed by the pod (defaults to 8082)",
37+
)
38+
39+
parser.add_argument(
40+
"--method",
41+
type=str,
42+
choices=["get", "post"],
43+
default="post",
44+
help="HTTP method to use: 'get' to read current log level, 'post' to set a log level",
45+
)
46+
return parser.parse_args(args)
47+
48+
49+
def port_forward(
50+
pod_name: str,
51+
local_port: int,
52+
remote_port: int,
53+
max_attempts: int = 5,
54+
) -> subprocess.Popen:
55+
"""Start a kubectl port-forward and wait until it is ready.
56+
57+
Returns the Popen handle so the caller can terminate it later.
58+
Raises RuntimeError if the port never becomes ready.
59+
"""
60+
61+
cmd = ["kubectl", "port-forward", pod_name, f"{local_port}:{remote_port}"]
62+
print("Starting port-forward:", " ".join(cmd))
63+
proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
64+
65+
for _attempt in range(1, max_attempts + 1):
66+
try:
67+
with socket.create_connection(("localhost", local_port), timeout=1):
68+
print(
69+
f"✅ Port-forward to {pod_name}:{remote_port} is ready on localhost:{local_port}"
70+
)
71+
return proc
72+
except OSError:
73+
time.sleep(0.4)
74+
75+
proc.terminate()
76+
proc.wait(timeout=5)
77+
raise RuntimeError(
78+
f"❌ Port-forward to {pod_name}:{remote_port} failed after {max_attempts} attempts."
79+
)
80+
81+
82+
def main():
83+
args = parse_args(sys.argv[1:])
84+
85+
# If a pod name is supplied, establish a port-forward before making the request
86+
port_forward_proc = None
87+
88+
target_port = args.monitoring_port
89+
base_port = args.local_port if args.pod_name else target_port
90+
91+
if args.pod_name:
92+
try:
93+
port_forward_proc = port_forward(args.pod_name, args.local_port, args.monitoring_port)
94+
except RuntimeError as err:
95+
print(err)
96+
sys.exit(1)
97+
98+
try:
99+
if args.method == "get":
100+
full_url = f"http://localhost:{base_port}/monitoring/logLevel"
101+
print(f"Fetching current log level from {full_url}")
102+
response = requests.get(full_url, timeout=5)
103+
104+
if response.status_code != 200:
105+
print(f"Failed to fetch log level: {response.status_code} {response.text}")
106+
sys.exit(1)
107+
108+
print("Current log level response:\n", response.text)
109+
elif args.method == "post":
110+
# Validate required arguments
111+
if not args.crate_name or not args.log_level:
112+
print("--crate_name and --log_level are required when --method=post")
113+
sys.exit(1)
114+
115+
base_url = f"http://localhost:{base_port}/monitoring/setLogLevel"
116+
full_url = f"{base_url}/{args.crate_name}/{args.log_level}"
117+
118+
print(f"Setting log level for {args.crate_name} to {args.log_level} at {full_url}")
119+
120+
response = requests.post(full_url, timeout=5)
121+
122+
if response.status_code != 200:
123+
print(
124+
f"❌ Failed to set log level for {args.crate_name} to {args.log_level}: {response.text}"
125+
)
126+
sys.exit(1)
127+
128+
print(f"✅ Successfully set log level for {args.crate_name} to {args.log_level}")
129+
else:
130+
print(f"Unsupported method {args.method}. Use 'get' or 'post'.")
131+
sys.exit(1)
132+
finally:
133+
# Clean up the port-forward process if we started one
134+
if port_forward_proc:
135+
port_forward_proc.send_signal(signal.SIGINT)
136+
try:
137+
port_forward_proc.wait(timeout=5)
138+
except subprocess.TimeoutExpired:
139+
port_forward_proc.kill()
140+
port_forward_proc.wait()
141+
142+
143+
if __name__ == "__main__":
144+
main()

0 commit comments

Comments
 (0)