# HG changeset patch # User Thierry Florac # Date 1574685575 -3600 # Node ID 1cedda2f84552854630852b1f9ea19cf9b8d767d # Parent 3d0e5eb0a181cf6254373f1145947e5bee318f5a Code cleanup diff -r 3d0e5eb0a181 -r 1cedda2f8455 src/pyams_apm.egg-info/PKG-INFO --- a/src/pyams_apm.egg-info/PKG-INFO Wed Feb 06 09:23:14 2019 +0100 +++ b/src/pyams_apm.egg-info/PKG-INFO Mon Nov 25 13:39:35 2019 +0100 @@ -6,9 +6,31 @@ Author: Thierry Florac Author-email: tflorac@ulthar.net License: ZPL -Description: - PyAMS APM - ========= +Description: ================= + PyAMS_apm package + ================= + + .. contents:: + + + What is PyAMS + ============= + + PyAMS (Pyramid Application Management Suite) is a small suite of packages written for applications + and content management with the Pyramid framework. + + **PyAMS** is actually mainly used to manage web sites through content management applications (CMS), + see PyAMS_content package), but many features are generic and can be used inside any kind of web + application. + + + What is PyAMS_apm ? + =================== + + APM in an Elasticsearch module which can be used to monitor applications performances. + + This package allows to integrate any Pyramid application with APM, providing a custom tween. + It also add instrumentation of several Python packages, like Chameleon or LDAP3. History diff -r 3d0e5eb0a181 -r 1cedda2f8455 src/pyams_apm.egg-info/requires.txt --- a/src/pyams_apm.egg-info/requires.txt Wed Feb 06 09:23:14 2019 +0100 +++ b/src/pyams_apm.egg-info/requires.txt Mon Nov 25 13:39:35 2019 +0100 @@ -1,5 +1,5 @@ setuptools -elastic-apm +elasticapm pyramid [test] diff -r 3d0e5eb0a181 -r 1cedda2f8455 src/pyams_apm/__init__.py --- a/src/pyams_apm/__init__.py Wed Feb 06 09:23:14 2019 +0100 +++ b/src/pyams_apm/__init__.py Mon Nov 25 13:39:35 2019 +0100 @@ -10,17 +10,15 @@ # FOR A PARTICULAR PURPOSE. # -__docformat__ = 'restructuredtext' - +"""PyAMS_apm package -# import standard library +This package provides an Elasticsearch APM integration for any Pyramid application. +""" -# import interfaces - -# import packages +__docformat__ = 'restructuredtext' def includeme(config): """pyams_apm features include""" - from .include import include_package + from .include import include_package # pylint: disable=import-outside-toplevel include_package(config) diff -r 3d0e5eb0a181 -r 1cedda2f8455 src/pyams_apm/include.py --- a/src/pyams_apm/include.py Wed Feb 06 09:23:14 2019 +0100 +++ b/src/pyams_apm/include.py Mon Nov 25 13:39:35 2019 +0100 @@ -10,7 +10,10 @@ # FOR A PARTICULAR PURPOSE. # -__docformat__ = 'restructuredtext' +"""PyAMS_apm.include module + +This module is used for Pyramid integration +""" import elasticapm from elasticapm.instrumentation import register @@ -18,8 +21,12 @@ from pyramid.interfaces import IApplicationCreated +__docformat__ = 'restructuredtext' + + @subscriber(IApplicationCreated) -def handle_apm_application(event): +def handle_apm_application(event): # pylint: disable=unused-argument + """Register custom instrumentations on application startup""" register.register('pyams_apm.packages.ldap3.LDAP3OpenInstrumentation') register.register('pyams_apm.packages.ldap3.LDAP3BindInstrumentation') register.register('pyams_apm.packages.ldap3.LDAP3SearchInstrumentation') diff -r 3d0e5eb0a181 -r 1cedda2f8455 src/pyams_apm/packages/__init__.py --- a/src/pyams_apm/packages/__init__.py Wed Feb 06 09:23:14 2019 +0100 +++ b/src/pyams_apm/packages/__init__.py Mon Nov 25 13:39:35 2019 +0100 @@ -1,20 +1,1 @@ # -# Copyright (c) 2008-2018 Thierry Florac -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# - -__docformat__ = 'restructuredtext' - - -# import standard library - -# import interfaces - -# import packages diff -r 3d0e5eb0a181 -r 1cedda2f8455 src/pyams_apm/packages/chameleon.py --- a/src/pyams_apm/packages/chameleon.py Wed Feb 06 09:23:14 2019 +0100 +++ b/src/pyams_apm/packages/chameleon.py Mon Nov 25 13:39:35 2019 +0100 @@ -10,30 +10,51 @@ # FOR A PARTICULAR PURPOSE. # -__docformat__ = 'restructuredtext' +"""PyAMS_apm.packages.chameleon module +This module adds APM instrumentation for Chameleon package +""" from elasticapm.instrumentation.packages.base import AbstractInstrumentedModule from elasticapm.traces import capture_span +__docformat__ = 'restructuredtext' + + class ChameleonCookingInstrumentation(AbstractInstrumentedModule): + """Chameleon cooking instrumentation""" + name = "chameleon_cooking" instrument_list = [("chameleon.template", "BaseTemplate.cook")] def call(self, module, method, wrapped, instance, args, kwargs): - with capture_span('COOK', "template.chameleon.cook", - {'filename': instance.filename}, leaf=True): + # pylint: disable=too-many-arguments + """Wrapped method call""" + with capture_span('COOK', + span_type='template', + span_subtype='chameleon', + span_action='cook', + extra={'filename': instance.filename}, + leaf=True): return wrapped(*args, **kwargs) class ChameleonRenderingInstrumentation(AbstractInstrumentedModule): + """Chameleon rendering instrumentation""" + name = "chameleon_rendering" instrument_list = [("chameleon.template", "BaseTemplate.render")] def call(self, module, method, wrapped, instance, args, kwargs): - with capture_span('RENDER', "template.chameleon.render", - {'filename': instance.filename}, leaf=True): + # pylint: disable=too-many-arguments + """Wrapped method call""" + with capture_span('RENDER', + span_type='template', + span_subtype='chameleon', + span_action='render', + extra={'filename': instance.filename}, + leaf=True): return wrapped(*args, **kwargs) diff -r 3d0e5eb0a181 -r 1cedda2f8455 src/pyams_apm/packages/ldap3.py --- a/src/pyams_apm/packages/ldap3.py Wed Feb 06 09:23:14 2019 +0100 +++ b/src/pyams_apm/packages/ldap3.py Mon Nov 25 13:39:35 2019 +0100 @@ -10,13 +10,21 @@ # FOR A PARTICULAR PURPOSE. # -__docformat__ = 'restructuredtext' +"""PyAMS_apm.packages.ldap3 module + +This module adds APM instrumentation to LDAP3 package +""" from elasticapm.instrumentation.packages.base import AbstractInstrumentedModule from elasticapm.traces import capture_span +__docformat__ = 'restructuredtext' + + class LDAP3OpenInstrumentation(AbstractInstrumentedModule): + """LDAP3 connection opening instrumentation""" + name = "ldap.open" instrument_list = [ @@ -25,26 +33,36 @@ ] def call(self, module, method, wrapped, instance, args, kwargs): + # pylint: disable=too-many-arguments + """Wrapped method call""" with capture_span('LDAP.OPEN', "db.ldap", leaf=True): return wrapped(*args, **kwargs) class LDAP3BindInstrumentation(AbstractInstrumentedModule): + """LDAP3 bind instrumentation""" + name = "ldap.bind" instrument_list = [("ldap3", "Connection.bind")] def call(self, module, method, wrapped, instance, args, kwargs): + # pylint: disable=too-many-arguments + """Wrapped method call""" with capture_span('LDAP.BIND', "db.ldap", leaf=True): return wrapped(*args, **kwargs) class LDAP3SearchInstrumentation(AbstractInstrumentedModule): + """LDAP3 search instrumentation""" + name = "ldap.search" instrument_list = [("ldap3", "Connection.search")] def call(self, module, method, wrapped, instance, args, kwargs): + # pylint: disable=too-many-arguments + """Wrapped method call""" with capture_span('LDAP.SEARCH', "db.ldap", { 'db': { 'type': 'ldap', @@ -55,6 +73,8 @@ class LDAP3GetResponseInstrumentation(AbstractInstrumentedModule): + """LDAP3 response getter instrumentation""" + name = "ldap.get_response" instrument_list = [ @@ -63,5 +83,7 @@ ] def call(self, module, method, wrapped, instance, args, kwargs): + # pylint: disable=too-many-arguments + """Wrapped method call""" with capture_span('LDAP.GET_RESPONSE', "db.ldap", leaf=True): return wrapped(*args, **kwargs) diff -r 3d0e5eb0a181 -r 1cedda2f8455 src/pyams_apm/tween.py --- a/src/pyams_apm/tween.py Wed Feb 06 09:23:14 2019 +0100 +++ b/src/pyams_apm/tween.py Mon Nov 25 13:39:35 2019 +0100 @@ -10,7 +10,11 @@ # FOR A PARTICULAR PURPOSE. # -__docformat__ = 'restructuredtext' +"""PyAMS_apm.tween module + +This module provides a custom tween which is used to integrate the Pyramid application +with APM, sending requests frames to the APM server. +""" import sys @@ -21,8 +25,11 @@ from pyramid.compat import reraise from pyramid.settings import asbool +__docformat__ = 'restructuredtext' + def list_from_setting(config, setting): + """Split configuration setting""" value = config.get(setting) if not value: return None @@ -30,6 +37,7 @@ def get_data_from_request(request): + """Extract main APM data from request properties""" data = { "headers": dict(**request.headers), "method": request.method, @@ -46,6 +54,7 @@ def get_data_from_response(response): + """Extract APM data from response properties""" data = {"status_code": response.status_int} if response.headers: data["headers"] = { @@ -55,7 +64,7 @@ return data -class elastic_apm_tween_factory(object): +class elastic_apm_tween_factory: # pylint: disable=invalid-name """Elasticsearch APM tween factory""" def __init__(self, handler, registry): @@ -89,7 +98,7 @@ transaction_result = response.status[0] + "xx" elasticapm.set_context(lambda: get_data_from_response(response), "response") return response - except Exception: + except Exception: # pylint: disable=broad-except transaction_result = '5xx' self.client.capture_exception( context={ @@ -107,6 +116,7 @@ view_name = '' transaction_name = request.matched_route.pattern if request.matched_route else view_name # prepend request method - transaction_name = " ".join((request.method, transaction_name)) if transaction_name else "" + transaction_name = " ".join((request.method, transaction_name)) \ + if transaction_name else "" elasticapm.set_context(lambda: get_data_from_request(request), "request") self.client.end_transaction(transaction_name, transaction_result)