-
Notifications
You must be signed in to change notification settings - Fork 421
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Move statsd out of core * Include statsd plugin by default * Rename config.registry.statsd to config.registry.metrics * Mock client instead of dynamically loaded function * Introduce the IMetricsInterface * Remove unused helper * Move instrumentation of backends and authentication out of kinto.core.statsd * Wrap event listeners to delay evaluation of config.registry.metrics after setup * Skip StatsD test with raw install * Move tests and assertions where they belong * Fix coverage to 100% * Adjust docs and deprecation warnings * Use single file instead of folder (like flush.py) * Mention statsd with uWsgi
- Loading branch information
Showing
16 changed files
with
509 additions
and
348 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import types | ||
|
||
from zope.interface import Interface | ||
|
||
from kinto.core import utils | ||
|
||
|
||
class IMetricsService(Interface): | ||
""" | ||
An interface that defines the metrics service contract. | ||
Any class implementing this must provide all its methods. | ||
""" | ||
|
||
def timer(key): | ||
""" | ||
Watch execution time. | ||
""" | ||
|
||
def count(key, count=1, unique=None): | ||
""" | ||
Count occurrences. If `unique` is set, overwrites the counter value | ||
on each call. | ||
""" | ||
|
||
|
||
def watch_execution_time(metrics_service, obj, prefix="", classname=None): | ||
""" | ||
Decorate all methods of an object in order to watch their execution time. | ||
Metrics will be named `{prefix}.{classname}.{method}`. | ||
""" | ||
classname = classname or utils.classname(obj) | ||
members = dir(obj) | ||
for name in members: | ||
value = getattr(obj, name) | ||
is_method = isinstance(value, types.MethodType) | ||
if not name.startswith("_") and is_method: | ||
statsd_key = f"{prefix}.{classname}.{name}" | ||
decorated_method = metrics_service.timer(statsd_key)(value) | ||
setattr(obj, name, decorated_method) | ||
|
||
|
||
def listener_with_timer(config, key, func): | ||
""" | ||
Add a timer with the specified `key` on the specified `func`. | ||
This is used to avoid evaluating `config.registry.metrics` during setup time | ||
to avoid having to deal with initialization order and configuration committing. | ||
""" | ||
|
||
def wrapped(*args, **kwargs): | ||
metrics_service = config.registry.metrics | ||
if not metrics_service: | ||
return func(*args, **kwargs) | ||
# If metrics are enabled, monitor execution time of listeners. | ||
with metrics_service.timer(key): | ||
return func(*args, **kwargs) | ||
|
||
return wrapped |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1 @@ | ||
import types | ||
from urllib.parse import urlparse | ||
|
||
from pyramid.exceptions import ConfigurationError | ||
|
||
from kinto.core import utils | ||
|
||
|
||
try: | ||
import statsd as statsd_module | ||
except ImportError: # pragma: no cover | ||
statsd_module = None | ||
|
||
|
||
class Client: | ||
def __init__(self, host, port, prefix): | ||
self._client = statsd_module.StatsClient(host, port, prefix=prefix) | ||
|
||
def watch_execution_time(self, obj, prefix="", classname=None): | ||
classname = classname or utils.classname(obj) | ||
members = dir(obj) | ||
for name in members: | ||
value = getattr(obj, name) | ||
is_method = isinstance(value, types.MethodType) | ||
if not name.startswith("_") and is_method: | ||
statsd_key = f"{prefix}.{classname}.{name}" | ||
decorated_method = self.timer(statsd_key)(value) | ||
setattr(obj, name, decorated_method) | ||
|
||
def timer(self, key): | ||
return self._client.timer(key) | ||
|
||
def count(self, key, count=1, unique=None): | ||
if unique is None: | ||
return self._client.incr(key, count=count) | ||
else: | ||
return self._client.set(key, unique) | ||
|
||
|
||
def statsd_count(request, count_key): | ||
statsd = request.registry.statsd | ||
if statsd: | ||
statsd.count(count_key) | ||
|
||
|
||
def load_from_config(config): | ||
# If this is called, it means that a ``statsd_url`` was specified in settings. | ||
# (see ``kinto.core.initialization``) | ||
# Raise a proper error if the ``statsd`` module is not installed. | ||
if statsd_module is None: | ||
error_msg = "Please install Kinto with monitoring dependencies (e.g. statsd package)" | ||
raise ConfigurationError(error_msg) | ||
|
||
settings = config.get_settings() | ||
uri = settings["statsd_url"] | ||
uri = urlparse(uri) | ||
|
||
if settings["project_name"] != "": | ||
prefix = settings["project_name"] | ||
else: | ||
prefix = settings["statsd_prefix"] | ||
|
||
return Client(uri.hostname, uri.port, prefix) | ||
from kinto.plugins.statsd import load_from_config # noqa: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.