Repository: jupyterhub/jupyterhub

Issue:
Auto-generate docs for prometheus metrics
It would probably be good to generate a doc with a list of prometheus metrics (like #2855). A bit of code like this to walk the metrics module can collect the relevant info:

```python
import jupyterhub.metrics

for name in dir(jupyterhub.metrics):
    obj = getattr(metrics, name)
    if obj.__class__.__module__.startswith('prometheus_client.'):
        for metric in obj.describe():
            print(metric.type, metric.name, metric.documentation)
```


Discussion:
@minrk I'd like to pick this 🤚 
@rajat404 wiee go for it! I'd appreciate this overview of the metrics myself I'm very happy about your help!

:heart: :star2:

Resolving patch:
diff --git a/docs/generate-metrics.py b/docs/generate-metrics.py
new file mode 100644
--- /dev/null
+++ b/docs/generate-metrics.py
@@ -0,0 +1,57 @@
+import os
+from os.path import join
+
+from pytablewriter import RstSimpleTableWriter
+from pytablewriter.style import Style
+
+import jupyterhub.metrics
+
+HERE = os.path.abspath(os.path.dirname(__file__))
+
+
+class Generator:
+    @classmethod
+    def create_writer(cls, table_name, headers, values):
+        writer = RstSimpleTableWriter()
+        writer.table_name = table_name
+        writer.headers = headers
+        writer.value_matrix = values
+        writer.margin = 1
+        [writer.set_style(header, Style(align="center")) for header in headers]
+        return writer
+
+    def _parse_metrics(self):
+        table_rows = []
+        for name in dir(jupyterhub.metrics):
+            obj = getattr(jupyterhub.metrics, name)
+            if obj.__class__.__module__.startswith('prometheus_client.'):
+                for metric in obj.describe():
+                    table_rows.append([metric.type, metric.name, metric.documentation])
+        return table_rows
+
+    def prometheus_metrics(self):
+        generated_directory = f"{HERE}/source/reference"
+        if not os.path.exists(generated_directory):
+            os.makedirs(generated_directory)
+
+        filename = f"{generated_directory}/metrics.rst"
+        table_name = ""
+        headers = ["Type", "Name", "Description"]
+        values = self._parse_metrics()
+        writer = self.create_writer(table_name, headers, values)
+
+        title = "List of Prometheus Metrics"
+        underline = "============================"
+        content = f"{title}\n{underline}\n{writer.dumps()}"
+        with open(filename, 'w') as f:
+            f.write(content)
+        print(f"Generated {filename}.")
+
+
+def main():
+    doc_generator = Generator()
+    doc_generator.prometheus_metrics()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs/source/conf.py b/docs/source/conf.py
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -217,10 +217,10 @@ def setup(app):
 on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
 if on_rtd:
     # readthedocs.org uses their theme by default, so no need to specify it
-    # build rest-api, since RTD doesn't run make
+    # build both metrics and rest-api, since RTD doesn't run make
     from subprocess import check_call as sh
 
-    sh(['make', 'rest-api'], cwd=docs)
+    sh(['make', 'metrics', 'rest-api'], cwd=docs)
 
 # -- Spell checking -------------------------------------------------------
 


Test patch: