Skip to content

Commit e05d3e5

Browse files
committed
changes of hatch run docs:api
1 parent 131b7a2 commit e05d3e5

File tree

3 files changed

+54
-9
lines changed

3 files changed

+54
-9
lines changed

docs/source/api/jupyter_server.prometheus.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ Submodules
1616
:show-inheritance:
1717
:undoc-members:
1818

19+
20+
.. automodule:: jupyter_server.prometheus.server
21+
:members:
22+
:show-inheritance:
23+
:undoc-members:
24+
1925
Module contents
2026
---------------
2127

jupyter_server/prometheus/server.py

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,6 @@ def start(self, port: int) -> None:
162162
port : int
163163
The port to listen on for metrics requests
164164
"""
165-
self.port = port
166-
167165
# Initialize Jupyter metrics
168166
self.initialize_metrics()
169167

@@ -184,9 +182,38 @@ def start(self, port: int) -> None:
184182
authenticate_metrics = main_app.settings.get("authenticate_prometheus", True)
185183
auth_info = "with authentication" if authenticate_metrics else "without authentication"
186184

187-
# Create and start the HTTP server
185+
# Create and start the HTTP server with port retry logic
188186
self.http_server = tornado.httpserver.HTTPServer(metrics_app)
189-
self.http_server.listen(port)
187+
188+
# Try to bind to the requested port, with fallback to random ports
189+
actual_port = port
190+
max_retries = 10
191+
192+
for attempt in range(max_retries):
193+
try:
194+
self.http_server.listen(actual_port)
195+
self.port = actual_port
196+
break
197+
except OSError as e:
198+
if e.errno == 98: # Address already in use
199+
if attempt == 0:
200+
# First attempt failed, try random ports
201+
import random
202+
actual_port = random.randint(49152, 65535) # Use dynamic port range
203+
else:
204+
# Subsequent attempts, try next random port
205+
actual_port = random.randint(49152, 65535)
206+
207+
if attempt == max_retries - 1:
208+
# Last attempt failed
209+
self.server_app.log.warning(
210+
f"Could not start metrics server on any port after {max_retries} attempts. "
211+
f"Metrics will be available on the main server at /metrics"
212+
)
213+
return
214+
else:
215+
# Non-port-related error, re-raise
216+
raise
190217

191218
# Start the IOLoop in a separate thread
192219
def start_metrics_loop():
@@ -198,7 +225,7 @@ def start_metrics_loop():
198225
self.thread.start()
199226

200227
self.server_app.log.info(
201-
f"Metrics server started on port {port} {auth_info} (using Jupyter Prometheus integration)"
228+
f"Metrics server started on port {self.port} {auth_info} (using Jupyter Prometheus integration)"
202229
)
203230

204231
def stop(self) -> None:

jupyter_server/serverapp.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3050,7 +3050,15 @@ def _start_metrics_server(self, port):
30503050
"""Start a separate metrics server on the specified port using Jupyter's Prometheus integration."""
30513051
from jupyter_server.prometheus.server import start_metrics_server
30523052

3053-
self.metrics_server = start_metrics_server(self, port)
3053+
try:
3054+
self.metrics_server = start_metrics_server(self, port)
3055+
# Check if the metrics server actually started (has a port)
3056+
if not hasattr(self.metrics_server, 'port') or self.metrics_server.port is None:
3057+
self.metrics_server = None
3058+
self.log.warning("Metrics server failed to start. Metrics will be available on the main server at /metrics")
3059+
except Exception as e:
3060+
self.metrics_server = None
3061+
self.log.warning(f"Failed to start metrics server: {e}. Metrics will be available on the main server at /metrics")
30543062

30553063
def launch_browser(self) -> None:
30563064
"""Launch the browser."""
@@ -3127,12 +3135,16 @@ def start_app(self) -> None:
31273135
# with auth info.
31283136

31293137
# Determine metrics URL based on whether separate metrics server is running
3130-
if self.metrics_port:
3138+
if (self.metrics_port and
3139+
hasattr(self, 'metrics_server') and
3140+
self.metrics_server is not None and
3141+
hasattr(self.metrics_server, 'port') and
3142+
self.metrics_server.port is not None):
31313143
# Separate metrics server is running
31323144
if self.authenticate_prometheus:
3133-
metrics_url = f"http://localhost:{self.metrics_port}/metrics?token={self.identity_provider.token}"
3145+
metrics_url = f"http://localhost:{self.metrics_server.port}/metrics?token={self.identity_provider.token}"
31343146
else:
3135-
metrics_url = f"http://localhost:{self.metrics_port}/metrics"
3147+
metrics_url = f"http://localhost:{self.metrics_server.port}/metrics"
31363148
else:
31373149
# Metrics are served on main server
31383150
# Use the connection_url as base and append /metrics

0 commit comments

Comments
 (0)