Skip to content

Commit

Permalink
switch to click for command-line parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
albertodonato committed Dec 13, 2024
1 parent 81ac1d5 commit c1758af
Show file tree
Hide file tree
Showing 11 changed files with 552 additions and 246 deletions.
112 changes: 73 additions & 39 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,25 @@ An example usage is the following:

.. code:: python
from prometheus_aioexporter import PrometheusExporterScript
import click
from prometheus_aioexporter import Arguments, PrometheusExporterScript
class MyExporter(PrometheusExporterScript):
"""My Prometheus exporter."""
name = "my-exporter"
default_port = 9091
envvar_prefix = "MYEXP"
def command_line_parameters(self) -> list[click.Parameter]:
# Additional options for the script
return [
click.Option(["--custom-option"], help="a custom option"),
...
]
def configure_argument_parser(
self, parser: argparse.ArgumentParser
) -> None:
# Additional arguments to the script
parser.add_argument("--custom-option", help="a custom option")
# ...
def configure(self, args: argparse.Namespace) -> None:
def configure(self, args: Arguments) -> None:
# Save attributes that are needed for later
self.data = do_stuff()
# ...
Expand All @@ -62,34 +65,7 @@ An example usage is the following:
script = MyExporter()
Exporter command-line
~~~~~~~~~~~~~~~~~~~~~

``PrometheusExporterScript`` provides a few command-line arguments by default:

.. code::
options:
-h, --help show this help message and exit
-H HOST [HOST ...], --host HOST [HOST ...]
host addresses to bind (default: ['localhost'])
-p PORT, --port PORT port to run the webserver on (default: 9090)
--metrics-path METRICS_PATH
path under which metrics are exposed (default: /metrics)
-L {critical,error,warning,info,debug}, --log-level {critical,error,warning,info,debug}
minimum level for log messages (default: info)
--log-format {plain,json}
log output format (default: plain)
--process-stats include process stats in metrics (default: False)
--ssl-private-key SSL_PRIVATE_KEY
full path to the ssl private key (default: None)
--ssl-public-key SSL_PUBLIC_KEY
full path to the ssl public key (default: None)
--ssl-ca SSL_CA full path to the ssl certificate authority (CA) (default: None)
Further options can be added by implementing ``configure_argument_parser()``,
which receives the ``argparse.ArgumentParser`` instance used by the script.
Also see the `sample script`_ for a complete example.

The ``script`` variable from the example above can be referenced in
``pyproject.toml`` to generate the script, like
Expand All @@ -103,17 +79,73 @@ The ``script`` variable from the example above can be referenced in
The ``description`` of the exporter can be customized by setting the docstring
in the script class.


Exporter command-line
~~~~~~~~~~~~~~~~~~~~~

``PrometheusExporterScript`` provides a few command-line arguments by default:

.. code::
Options:
-H, --host TEXT host addresses to bind [env var: EXP_HOST;
default: localhost]
-p, --port INTEGER port to run the webserver on [env var:
EXP_PORT; default: 9091]
--metrics-path TEXT path under which metrics are exposed [env
var: EXP_METRICS_PATH; default: /metrics]
-L, --log-level [critical|error|warning|info|debug]
minimum level for log messages [env var:
EXP_LOG_LEVEL; default: info]
--log-format [plain|json] log output format [env var: EXP_LOG_FORMAT;
default: plain]
--process-stats include process stats in metrics [env var:
EXP_PROCESS_STATS]
--ssl-private-key FILE full path to the ssl private key [env var:
EXP_SSL_PRIVATE_KEY]
--ssl-public-key FILE full path to the ssl public key [env var:
EXP_SSL_PUBLIC_KEY]
--ssl-ca FILE full path to the ssl certificate authority
(CA) [env var: EXP_SSL_CA]
--version Show the version and exit.
--help Show this message and exit.
Further options can be added by implementing ``command_line_parameters()`` to
return additional ``click.Argument`` and ``click.Option`` items to add to the
command line.

See the Click_ manual for more details on available parameter types.

In order to serve metrics on the HTTPS endpoint both ``ssl-private-key`` and
``ssl-public-key`` need to be define. The ssl certificate authority
(i.e. ``ssl-ca``) is optional.


Environment variables
~~~~~~~~~~~~~~~~~~~~~

Values from default arguments can also be supplied via environment variables.
Variables names match the ``<envvar_prefix>_<option_with_underscores`` format,
so, for instance, the ``--port`` option can be provided as ``MYEXP_PORT=9091``
(assuming the ``PrometheusExporterScript.envvar_prefix`` is set to ``MYEXP``).

Provided command-line options take precedence over environment variables.

It's also possible to provide environment variables via dotenv file. By default
``.env`` is looked up in the current working directory. The file to load can be
overridden by setting the file path via the ``<envvar_prefix>_DOTENV``
variable.

Explicitly provided environment variables take precedence over the ones defined
in the dotenv file.


Startup configuration
~~~~~~~~~~~~~~~~~~~~~

Additional initial setup (e.g. config file parsing) can be performed by the
script by implementing the ``configure()``. This is called at startup with the
parsed argument (an ``argparse.Namespace`` instance).
parsed arguments (an ``Arguments`` instance).


Metrics configuration
Expand All @@ -124,7 +156,7 @@ with a list of ``MetricConfig``\s. This is typically done in ``configure()``:

.. code:: python
def configure(self, args: argparse.Namespace) -> None:
def configure(self, args: Arguments) -> None:
# ...
self.create_metrics(
[
Expand Down Expand Up @@ -166,6 +198,8 @@ run as ``prometheus-aioexporter-sample``).


.. _Prometheus: https://prometheus.io/
.. _Click: https://click.palletsprojects.com/en/stable/
.. _sample script: ./prometheus_aioexporter/sample.py

.. |Latest Version| image:: https://img.shields.io/pypi/v/prometheus-aioexporter.svg
:alt: Latest Version
Expand Down
3 changes: 2 additions & 1 deletion prometheus_aioexporter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
MetricConfig,
MetricsRegistry,
)
from ._script import PrometheusExporterScript
from ._script import Arguments, PrometheusExporterScript

__all__ = [
"Arguments",
"InvalidMetricType",
"MetricConfig",
"MetricsRegistry",
Expand Down
8 changes: 4 additions & 4 deletions prometheus_aioexporter/_log.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from enum import StrEnum
from functools import cached_property
import logging
from typing import cast
import typing as t

from aiohttp.abc import AbstractAccessLogger
from aiohttp.web import BaseRequest, StreamResponse
Expand Down Expand Up @@ -29,7 +29,7 @@ class LogLevel(StrEnum):

def num_level(self) -> int:
"""Return the numeric level."""
return cast(int, getattr(logging, self.name))
return t.cast(int, getattr(logging, self.name))

def __repr__(self) -> str:
return self.value
Expand All @@ -39,8 +39,8 @@ class AccessLogger(AbstractAccessLogger):
"""Access logger for aiohttp."""

@cached_property
def _logger(self) -> structlog.BoundLogger:
return cast(structlog.BoundLogger, structlog.get_logger())
def _logger(self) -> structlog.stdlib.BoundLogger:
return t.cast(structlog.stdlib.BoundLogger, structlog.get_logger())

def log(
self, request: BaseRequest, response: StreamResponse, time: float
Expand Down
4 changes: 2 additions & 2 deletions prometheus_aioexporter/_metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
dataclass,
field,
)
from typing import Any
import typing as t

from prometheus_client import (
CollectorRegistry,
Expand Down Expand Up @@ -48,7 +48,7 @@ class MetricConfig:
description: str
type: str
labels: Iterable[str] = field(default_factory=tuple)
config: dict[str, Any] = field(default_factory=dict)
config: dict[str, t.Any] = field(default_factory=dict)

def __post_init__(self) -> None:
self.labels = tuple(sorted(self.labels))
Expand Down
Loading

0 comments on commit c1758af

Please sign in to comment.