kinto 19.2.0__py3-none-any.whl → 19.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kinto might be problematic. Click here for more details.
- kinto/__init__.py +1 -0
- kinto/core/__init__.py +1 -0
- kinto/core/initialization.py +57 -7
- kinto/core/metrics.py +37 -1
- kinto/core/utils.py +8 -0
- kinto/plugins/admin/VERSION +1 -1
- kinto/plugins/admin/build/VERSION +1 -1
- kinto/plugins/admin/build/assets/index-BKIg2XW8.js +165 -0
- kinto/plugins/admin/build/assets/{index-vylaZGUr.css → index-D8oiN37x.css} +1 -1
- kinto/plugins/admin/build/assets/{javascript-upQ8KtFH.js → javascript-iSgyE4tI.js} +1 -1
- kinto/plugins/admin/build/index.html +2 -2
- kinto/plugins/prometheus.py +56 -20
- kinto/plugins/statsd.py +13 -1
- {kinto-19.2.0.dist-info → kinto-19.3.0.dist-info}/METADATA +3 -3
- {kinto-19.2.0.dist-info → kinto-19.3.0.dist-info}/RECORD +28 -28
- {kinto-19.2.0.dist-info → kinto-19.3.0.dist-info}/WHEEL +1 -1
- kinto/plugins/admin/build/assets/index-iVTdxamX.js +0 -175
- /kinto/plugins/admin/build/assets/{asn1-8gHclKtu.js → asn1-CGOzndHr.js} +0 -0
- /kinto/plugins/admin/build/assets/{clojure-plf_rynZ.js → clojure-BMjYHr_A.js} +0 -0
- /kinto/plugins/admin/build/assets/{css-tpsEXL3H.js → css-BnMrqG3P.js} +0 -0
- /kinto/plugins/admin/build/assets/{logo-FQUYikj1.png → logo-VBRiKSPX.png} +0 -0
- /kinto/plugins/admin/build/assets/{mllike-ilm95jrV.js → mllike-C_8OmSiT.js} +0 -0
- /kinto/plugins/admin/build/assets/{python-xljIYvii.js → python-BuPzkPfP.js} +0 -0
- /kinto/plugins/admin/build/assets/{rpm-cddeyEgF.js → rpm-CTu-6PCP.js} +0 -0
- /kinto/plugins/admin/build/assets/{sql-3IaSLchm.js → sql-C4g8LzGK.js} +0 -0
- /kinto/plugins/admin/build/assets/{ttcn-cfg-9oMIyPXS.js → ttcn-cfg-BIkV9KBc.js} +0 -0
- {kinto-19.2.0.dist-info → kinto-19.3.0.dist-info}/LICENSE +0 -0
- {kinto-19.2.0.dist-info → kinto-19.3.0.dist-info}/entry_points.txt +0 -0
- {kinto-19.2.0.dist-info → kinto-19.3.0.dist-info}/top_level.txt +0 -0
kinto/__init__.py
CHANGED
kinto/core/__init__.py
CHANGED
kinto/core/initialization.py
CHANGED
|
@@ -431,6 +431,9 @@ def setup_logging(config):
|
|
|
431
431
|
def setup_metrics(config):
|
|
432
432
|
settings = config.get_settings()
|
|
433
433
|
|
|
434
|
+
# Register a no-op metrics service by default.
|
|
435
|
+
config.registry.registerUtility(metrics.NoOpMetricsService(), metrics.IMetricsService)
|
|
436
|
+
|
|
434
437
|
# This does not fully respect the Pyramid/ZCA patterns, but the rest of Kinto uses
|
|
435
438
|
# `registry.storage`, `registry.cache`, etc. Consistency seems more important.
|
|
436
439
|
config.registry.__class__.metrics = property(
|
|
@@ -449,9 +452,6 @@ def setup_metrics(config):
|
|
|
449
452
|
def on_app_created(event):
|
|
450
453
|
config = event.app
|
|
451
454
|
metrics_service = config.registry.metrics
|
|
452
|
-
if not metrics_service:
|
|
453
|
-
logger.warning("No metrics service registered.")
|
|
454
|
-
return
|
|
455
455
|
|
|
456
456
|
metrics.watch_execution_time(metrics_service, config.registry.cache, prefix="backend")
|
|
457
457
|
metrics.watch_execution_time(metrics_service, config.registry.storage, prefix="backend")
|
|
@@ -471,15 +471,65 @@ def setup_metrics(config):
|
|
|
471
471
|
def on_new_response(event):
|
|
472
472
|
request = event.request
|
|
473
473
|
metrics_service = config.registry.metrics
|
|
474
|
-
|
|
475
|
-
|
|
474
|
+
|
|
475
|
+
try:
|
|
476
|
+
endpoint = utils.strip_uri_prefix(request.path)
|
|
477
|
+
except UnicodeDecodeError as e:
|
|
478
|
+
# This `on_new_response` callback is also called when a HTTP 400
|
|
479
|
+
# is returned because of an invalid UTF-8 path. We still want metrics.
|
|
480
|
+
endpoint = str(e)
|
|
476
481
|
|
|
477
482
|
# Count unique users.
|
|
478
483
|
user_id = request.prefixed_userid
|
|
479
484
|
if user_id:
|
|
480
485
|
# Get rid of colons in metric packet (see #1282).
|
|
481
|
-
user_id = user_id.
|
|
482
|
-
metrics_service.count("users", unique=user_id)
|
|
486
|
+
auth, user_id = user_id.split(":")
|
|
487
|
+
metrics_service.count("users", unique=[("auth", auth), ("userid", user_id)])
|
|
488
|
+
|
|
489
|
+
# Add extra labels to metrics, based on fields extracted from the request matchdict.
|
|
490
|
+
metrics_matchdict_fields = aslist(settings["metrics_matchdict_fields"])
|
|
491
|
+
# Turn the `id` field of object endpoints into `{resource}_id` (eg. `mushroom_id`, `bucket_id`)
|
|
492
|
+
enhanced_matchdict = dict(request.matchdict or {})
|
|
493
|
+
try:
|
|
494
|
+
enhanced_matchdict[request.current_resource_name + "_id"] = enhanced_matchdict.get(
|
|
495
|
+
"id", ""
|
|
496
|
+
)
|
|
497
|
+
except AttributeError:
|
|
498
|
+
# Not on a resource.
|
|
499
|
+
pass
|
|
500
|
+
metrics_matchdict_labels = [
|
|
501
|
+
(field, enhanced_matchdict.get(field, "")) for field in metrics_matchdict_fields
|
|
502
|
+
]
|
|
503
|
+
|
|
504
|
+
# Count served requests.
|
|
505
|
+
metrics_service.count(
|
|
506
|
+
"request_summary",
|
|
507
|
+
unique=[
|
|
508
|
+
("method", request.method.lower()),
|
|
509
|
+
("endpoint", endpoint),
|
|
510
|
+
("status", str(request.response.status_code)),
|
|
511
|
+
]
|
|
512
|
+
+ metrics_matchdict_labels,
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
try:
|
|
516
|
+
current = utils.msec_time()
|
|
517
|
+
duration = current - request._received_at
|
|
518
|
+
metrics_service.observe(
|
|
519
|
+
"request_duration",
|
|
520
|
+
duration,
|
|
521
|
+
labels=[("endpoint", endpoint)] + metrics_matchdict_labels,
|
|
522
|
+
)
|
|
523
|
+
except AttributeError: # pragma: no cover
|
|
524
|
+
# Logging was not setup in this Kinto app (unlikely but possible)
|
|
525
|
+
pass
|
|
526
|
+
|
|
527
|
+
# Observe response size.
|
|
528
|
+
metrics_service.observe(
|
|
529
|
+
"request_size",
|
|
530
|
+
len(request.response.body or b""),
|
|
531
|
+
labels=[("endpoint", endpoint)] + metrics_matchdict_labels,
|
|
532
|
+
)
|
|
483
533
|
|
|
484
534
|
# Count authentication verifications.
|
|
485
535
|
if hasattr(request, "authn_type"):
|
kinto/core/metrics.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import types
|
|
2
2
|
|
|
3
|
-
from zope.interface import Interface
|
|
3
|
+
from zope.interface import Interface, implementer
|
|
4
4
|
|
|
5
5
|
from kinto.core import utils
|
|
6
6
|
|
|
@@ -16,13 +16,47 @@ class IMetricsService(Interface):
|
|
|
16
16
|
Watch execution time.
|
|
17
17
|
"""
|
|
18
18
|
|
|
19
|
+
def observe(self, key, value, labels=[]):
|
|
20
|
+
"""
|
|
21
|
+
Observe a give `value` for the specified `key`.
|
|
22
|
+
"""
|
|
23
|
+
|
|
19
24
|
def count(key, count=1, unique=None):
|
|
20
25
|
"""
|
|
21
26
|
Count occurrences. If `unique` is set, overwrites the counter value
|
|
22
27
|
on each call.
|
|
28
|
+
|
|
29
|
+
`unique` should be of type ``list[tuple[str,str]]``.
|
|
23
30
|
"""
|
|
24
31
|
|
|
25
32
|
|
|
33
|
+
class NoOpTimer:
|
|
34
|
+
def __call__(self, f):
|
|
35
|
+
@utils.safe_wraps(f)
|
|
36
|
+
def _wrapped(*args, **kwargs):
|
|
37
|
+
return f(*args, **kwargs)
|
|
38
|
+
|
|
39
|
+
return _wrapped
|
|
40
|
+
|
|
41
|
+
def __enter__(self):
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
def __exit__(self, *args, **kwargs):
|
|
45
|
+
pass
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@implementer(IMetricsService)
|
|
49
|
+
class NoOpMetricsService:
|
|
50
|
+
def timer(self, key):
|
|
51
|
+
return NoOpTimer()
|
|
52
|
+
|
|
53
|
+
def observe(self, key, value, labels=[]):
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
def count(self, key, count=1, unique=None):
|
|
57
|
+
pass
|
|
58
|
+
|
|
59
|
+
|
|
26
60
|
def watch_execution_time(metrics_service, obj, prefix="", classname=None):
|
|
27
61
|
"""
|
|
28
62
|
Decorate all methods of an object in order to watch their execution time.
|
|
@@ -49,6 +83,8 @@ def listener_with_timer(config, key, func):
|
|
|
49
83
|
def wrapped(*args, **kwargs):
|
|
50
84
|
metrics_service = config.registry.metrics
|
|
51
85
|
if not metrics_service:
|
|
86
|
+
# This only happens if `kinto.core.initialization.setup_metrics` is
|
|
87
|
+
# not listed in the `initialization_sequence` setting.
|
|
52
88
|
return func(*args, **kwargs)
|
|
53
89
|
# If metrics are enabled, monitor execution time of listeners.
|
|
54
90
|
with metrics_service.timer(key):
|
kinto/core/utils.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import collections.abc as collections_abc
|
|
2
|
+
import functools
|
|
2
3
|
import hashlib
|
|
3
4
|
import hmac
|
|
4
5
|
import os
|
|
@@ -541,3 +542,10 @@ def apply_json_patch(obj, ops):
|
|
|
541
542
|
raise ValueError(e)
|
|
542
543
|
|
|
543
544
|
return result
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
def safe_wraps(wrapper, *args, **kwargs):
|
|
548
|
+
"""Safely wraps partial functions."""
|
|
549
|
+
while isinstance(wrapper, functools.partial):
|
|
550
|
+
wrapper = wrapper.func
|
|
551
|
+
return functools.wraps(wrapper, *args, **kwargs)
|
kinto/plugins/admin/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.4.1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.4.1
|