Skip to content

Commit 3f6cf36

Browse files
committed
Add a /metrics endpoint for Prometheus Metrics
[Prometheus](https://prometheus.io/) provides a standard metrics format that can be collected and used in many contexts. - From the browser to drive 'current resource usage' displays, such as https://github.com/yuvipanda/nbresuse - From a prometheus server to collect historical data for operational analysis and performance monitoring Example: https://grafana.mybinder.org/dashboard/db/1-overview?refresh=1m&orgId=1 for mybinder.org metrics from JupyterHub and BinderHub, via prometheus server at https://prometheus.mybinder.org The JupyterHub and BinderHub projects already expose Prometheus metrics natively. Adding this to the Jupyter notebook server allows us to instrument the code easily and in a standard format that has lots of 3rd party tooling for it. This commit does the following: - Introduce the `prometheus_client` library as a dependency. This library has no dependencies of its own and is pure python. - Add an authenticated `/metrics` endpoint to the server, which returns metrics in Prometheus Text Format - Expose the default process metrics from `prometheus_client`, which include memory usage and CPU usage info (for just the notebook process)
1 parent faa0cab commit 3f6cf36

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

notebook/base/handlers.py

+12
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from jinja2 import TemplateNotFound
2929
from tornado import web, gen, escape, httputil
3030
from tornado.log import app_log
31+
import prometheus_client
3132

3233
from notebook._sysinfo import get_sys_info
3334

@@ -809,6 +810,16 @@ def get(self):
809810
url = sep.join([self._url, self.request.query])
810811
self.redirect(url, permanent=self._permanent)
811812

813+
class PrometheusMetricsHandler(IPythonHandler):
814+
"""
815+
Return prometheus metrics for this notebook server
816+
"""
817+
@web.authenticated
818+
def get(self):
819+
self.set_header('Content-Type', prometheus_client.CONTENT_TYPE_LATEST)
820+
self.write(prometheus_client.generate_latest(prometheus_client.REGISTRY))
821+
822+
812823
#-----------------------------------------------------------------------------
813824
# URL pattern fragments for re-use
814825
#-----------------------------------------------------------------------------
@@ -825,4 +836,5 @@ def get(self):
825836
(r".*/", TrailingSlashHandler),
826837
(r"api", APIVersionHandler),
827838
(r'/(robots\.txt|favicon\.ico)', web.StaticFileHandler),
839+
(r'/metrics', PrometheusMetricsHandler)
828840
]

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
'ipykernel', # bless IPython kernel for now
8989
'Send2Trash',
9090
'terminado>=0.8.1'
91+
'prometheus_client'
9192
],
9293
extras_require = {
9394
'test:python_version == "2.7"': ['mock'],

0 commit comments

Comments
 (0)