wrapture-instrumentation 1.0.0.dev7__tar.gz → 1.0.0.dev8__tar.gz
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.
- wrapture_instrumentation-1.0.0.dev8/CHANGES.md +373 -0
- {wrapture_instrumentation-1.0.0.dev7/src/wrapture_instrumentation.egg-info → wrapture_instrumentation-1.0.0.dev8}/PKG-INFO +19 -6
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/README.md +17 -4
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/TESTING.md +7 -3
- wrapture_instrumentation-1.0.0.dev8/demo/database_sqlalchemy.py +183 -0
- wrapture_instrumentation-1.0.0.dev8/demo/external_aiohttp.py +142 -0
- wrapture_instrumentation-1.0.0.dev8/demo/external_httpx.py +136 -0
- wrapture_instrumentation-1.0.0.dev8/demo/external_requests.py +121 -0
- wrapture_instrumentation-1.0.0.dev8/demo/external_urllib3.py +145 -0
- wrapture_instrumentation-1.0.0.dev8/demo/framework_fastapi.py +151 -0
- wrapture_instrumentation-1.0.0.dev8/demo/framework_starlette.py +136 -0
- wrapture_instrumentation-1.0.0.dev8/demo/rpc_grpc.py +127 -0
- wrapture_instrumentation-1.0.0.dev8/demo/server_aiohttp.py +171 -0
- wrapture_instrumentation-1.0.0.dev8/demo/server_uvicorn.py +182 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/server_werkzeug.py +6 -2
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/pyproject.toml +53 -5
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/__init__.py +1 -1
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/database/sqlalchemy/README.md +114 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/database/sqlalchemy/__init__.py +95 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/database/sqlalchemy/dialects.py +42 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/database/sqlalchemy/engine_base.py +73 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/database/sqlalchemy/engine_default.py +181 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/aiohttp_client/README.md +97 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/aiohttp_client/__init__.py +56 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/aiohttp_client/client.py +192 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/httpx/README.md +118 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/httpx/__init__.py +56 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/httpx/_client.py +222 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/requests/README.md +106 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/requests/__init__.py +54 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/requests/sessions.py +215 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/urllib3/README.md +98 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/urllib3/__init__.py +69 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/external/urllib3/pools.py +213 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/framework/fastapi/README.md +97 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/framework/fastapi/__init__.py +54 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/framework/fastapi/applications.py +99 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/framework/fastapi/routing.py +111 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/framework/starlette/README.md +93 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/framework/starlette/__init__.py +55 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/framework/starlette/applications.py +105 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/framework/starlette/routing.py +106 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/rpc/__init__.py +2 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/rpc/grpc/README.md +102 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/rpc/grpc/__init__.py +65 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/rpc/grpc/interceptors.py +416 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/server/aiohttp_web/README.md +89 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/server/aiohttp_web/__init__.py +62 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/server/aiohttp_web/web_app.py +192 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/server/aiohttp_web/web_urldispatcher.py +78 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/server/uvicorn/README.md +86 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/server/uvicorn/__init__.py +51 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation/server/uvicorn/config.py +135 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation.egg-info}/PKG-INFO +19 -6
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation.egg-info/SOURCES.txt +130 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation.egg-info/entry_points.txt +10 -0
- wrapture_instrumentation-1.0.0.dev8/src/wrapture_instrumentation.egg-info/requires.txt +1 -0
- wrapture_instrumentation-1.0.0.dev8/tests/asgi.py +156 -0
- wrapture_instrumentation-1.0.0.dev8/tests/database/sqlalchemy/conftest.py +23 -0
- wrapture_instrumentation-1.0.0.dev8/tests/database/sqlalchemy/test_apply_remove.py +83 -0
- wrapture_instrumentation-1.0.0.dev8/tests/database/sqlalchemy/test_class.py +79 -0
- wrapture_instrumentation-1.0.0.dev8/tests/database/sqlalchemy/test_composition.py +107 -0
- wrapture_instrumentation-1.0.0.dev8/tests/database/sqlalchemy/test_recording.py +261 -0
- wrapture_instrumentation-1.0.0.dev8/tests/database/sqlalchemy/test_registration.py +95 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/aiohttp_client/conftest.py +48 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/aiohttp_client/test_apply_remove.py +47 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/aiohttp_client/test_class.py +75 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/aiohttp_client/test_composition.py +69 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/aiohttp_client/test_propagation.py +116 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/aiohttp_client/test_recording.py +264 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/aiohttp_client/test_registration.py +84 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/httpx/conftest.py +23 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/httpx/test_apply_remove.py +47 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/httpx/test_async.py +126 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/httpx/test_class.py +69 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/httpx/test_propagation.py +103 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/httpx/test_recording.py +254 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/httpx/test_registration.py +81 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/requests/conftest.py +23 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/requests/test_apply_remove.py +45 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/requests/test_class.py +70 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/requests/test_propagation.py +103 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/requests/test_recording.py +249 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/requests/test_registration.py +82 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/urllib3/conftest.py +23 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/urllib3/test_apply_remove.py +52 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/urllib3/test_class.py +63 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/urllib3/test_composition.py +74 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/urllib3/test_propagation.py +63 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/urllib3/test_recording.py +174 -0
- wrapture_instrumentation-1.0.0.dev8/tests/external/urllib3/test_registration.py +76 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi/conftest.py +18 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi/shop.py +56 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi/test_apply_remove.py +46 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi/test_class.py +63 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi/test_composition.py +72 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi/test_registration.py +74 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi/test_request_options.py +43 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi/test_tracing.py +166 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/conftest.py +18 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/shop.py +50 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/test_apply_remove.py +46 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/test_class.py +64 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/test_composition.py +52 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/test_registration.py +74 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/test_request_options.py +43 -0
- wrapture_instrumentation-1.0.0.dev8/tests/framework/starlette/test_tracing.py +141 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/conftest.py +69 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/service.py +109 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/test_apply_remove.py +71 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/test_class.py +69 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/test_propagation.py +62 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/test_recording.py +157 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/test_registration.py +103 -0
- wrapture_instrumentation-1.0.0.dev8/tests/rpc/grpc/test_server.py +118 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/conftest.py +75 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/shop.py +49 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/test_apply_remove.py +105 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/test_class.py +68 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/test_composition.py +55 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/test_join.py +49 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/test_recording.py +180 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/aiohttp_web/test_registration.py +92 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn/conftest.py +117 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn/test_apply_remove.py +86 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn/test_class.py +64 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn/test_composition.py +101 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn/test_recording.py +88 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/uvicorn/test_registration.py +98 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/werkzeug_serving/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/werkzeug_serving/conftest.py +5 -1
- wrapture_instrumentation-1.0.0.dev8/tests/server/wsgiref_simple_server/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/server/xmlrpc_server/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/template/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/template/jinja2/__init__.py +0 -0
- wrapture_instrumentation-1.0.0.dev8/tests/test_asgi.py +75 -0
- wrapture_instrumentation-1.0.0.dev7/CHANGES.md +0 -164
- wrapture_instrumentation-1.0.0.dev7/src/wrapture_instrumentation.egg-info/requires.txt +0 -1
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/LICENSE +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/MANIFEST.in +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/database_sqlite3.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/external_http_client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/external_urllib_request.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/external_xmlrpc_client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/framework_flask.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/server_wsgiref.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/server_xmlrpc.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/demo/template_jinja2.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/setup.cfg +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/database/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/database/sqlite3/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/database/sqlite3/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/database/sqlite3/dbapi2.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/http_client/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/http_client/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/http_client/client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/urllib_request/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/urllib_request/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/urllib_request/request.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/xmlrpc_client/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/xmlrpc_client/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/external/xmlrpc_client/client.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/framework/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/framework/flask/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/framework/flask/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/framework/flask/app.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/framework/flask/blueprints.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/framework/flask/common.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/framework/flask/scaffold.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/framework/flask/templating.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/py.typed +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/werkzeug_serving/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/werkzeug_serving/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/werkzeug_serving/serving.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/wsgiref_simple_server/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/wsgiref_simple_server/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/wsgiref_simple_server/simple_server.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/xmlrpc_server/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/xmlrpc_server/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/server/xmlrpc_server/server.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/template/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/template/jinja2/README.md +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/template/jinja2/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation/template/jinja2/environment.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation.egg-info/dependency_links.txt +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation.egg-info/not-zip-safe +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/src/wrapture_instrumentation.egg-info/top_level.txt +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/database/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/database/sqlite3 → wrapture_instrumentation-1.0.0.dev8/tests/database/sqlalchemy}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/external → wrapture_instrumentation-1.0.0.dev8/tests/database/sqlite3}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/database/sqlite3/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/database/sqlite3/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/database/sqlite3/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/database/sqlite3/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/database/sqlite3/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/external/http_client → wrapture_instrumentation-1.0.0.dev8/tests/external}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/external/urllib_request → wrapture_instrumentation-1.0.0.dev8/tests/external/aiohttp_client}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/external/xmlrpc_client → wrapture_instrumentation-1.0.0.dev8/tests/external/http_client}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/http_client/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/http_client/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/http_client/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/http_client/test_layering.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/http_client/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/http_client/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/framework → wrapture_instrumentation-1.0.0.dev8/tests/external/httpx}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/framework/flask → wrapture_instrumentation-1.0.0.dev8/tests/external/requests}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/server → wrapture_instrumentation-1.0.0.dev8/tests/external/urllib3}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/server/werkzeug_serving → wrapture_instrumentation-1.0.0.dev8/tests/external/urllib_request}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/urllib_request/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/urllib_request/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/urllib_request/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/urllib_request/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/urllib_request/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/urllib_request/test_requests.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/server/wsgiref_simple_server → wrapture_instrumentation-1.0.0.dev8/tests/external/xmlrpc_client}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/xmlrpc_client/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/xmlrpc_client/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/xmlrpc_client/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/xmlrpc_client/test_propagation.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/xmlrpc_client/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/external/xmlrpc_client/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/server/xmlrpc_server → wrapture_instrumentation-1.0.0.dev8/tests/framework}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/template → wrapture_instrumentation-1.0.0.dev8/tests/framework/fastapi}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7/tests/template/jinja2 → wrapture_instrumentation-1.0.0.dev8/tests/framework/flask}/__init__.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/portal.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/shop.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/test_lifecycle.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/test_request_options.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/test_templating.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/framework/flask/test_tracing.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/httpserver.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/werkzeug_serving/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/werkzeug_serving/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/werkzeug_serving/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/werkzeug_serving/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/werkzeug_serving/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/wsgiref_simple_server/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/wsgiref_simple_server/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/wsgiref_simple_server/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/wsgiref_simple_server/test_composition.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/wsgiref_simple_server/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/wsgiref_simple_server/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/xmlrpc_server/conftest.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/xmlrpc_server/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/xmlrpc_server/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/xmlrpc_server/test_join.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/xmlrpc_server/test_recording.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/server/xmlrpc_server/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/template/jinja2/test_apply_remove.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/template/jinja2/test_class.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/template/jinja2/test_registration.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/template/jinja2/test_rendering.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/template/jinja2/test_with_flask.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/test_package.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/test_wsgi.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/wsgi.py +0 -0
- {wrapture_instrumentation-1.0.0.dev7 → wrapture_instrumentation-1.0.0.dev8}/tests/xmlrpcserver.py +0 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
# Changes
|
|
2
|
+
|
|
3
|
+
## Version 1.0.0
|
|
4
|
+
|
|
5
|
+
In development.
|
|
6
|
+
|
|
7
|
+
- Package layout: the targets are grouped in role directories named
|
|
8
|
+
for their categories (`framework/flask`, `external/urllib_request`,
|
|
9
|
+
`server/xmlrpc_server`), the collection form of the naming
|
|
10
|
+
guidance, a single-target package keeping the flat
|
|
11
|
+
`<category>_<target>` name. Entry point names are unchanged, so
|
|
12
|
+
nothing a config says is affected.
|
|
13
|
+
|
|
14
|
+
- urllib (`urllib.request`, standard library): every request made
|
|
15
|
+
through `urllib.request`, by `urlopen`, `urlretrieve`, a custom opener or
|
|
16
|
+
another standard library module, records as one external leaf on
|
|
17
|
+
`OpenerDirector.open`, carrying the external category's contract
|
|
18
|
+
keys (method, URL without its query string, host, port, path, the
|
|
19
|
+
query with secrets masked, and the status whether returned or
|
|
20
|
+
raised as an `HTTPError`); a redirect is one event named by the
|
|
21
|
+
URL asked for. The trace identity from `wrapture.trace_headers()`
|
|
22
|
+
is added to every request's headers, hop by hop, leaving a header
|
|
23
|
+
the application set alone. The query is recorded through
|
|
24
|
+
`wrapture.capture_query()`, so the built-in sensitive names are
|
|
25
|
+
always masked, the body reduces to its size and the response to
|
|
26
|
+
its type. Three settings: `leaf` (off to see the nested opens and
|
|
27
|
+
anything instrumented beneath) and `propagate`, both on by
|
|
28
|
+
default, and `redact` (query parameters masked by name on top of
|
|
29
|
+
the built-in set). Supports Python 3.12 and later, the standard
|
|
30
|
+
library's version being the interpreter's.
|
|
31
|
+
|
|
32
|
+
- http.client (`http.client`, standard library): the wire layer
|
|
33
|
+
beneath urllib, urllib3 and xmlrpc.client, recorded phase by phase
|
|
34
|
+
as plain events: `connect` nested inside the phase that first
|
|
35
|
+
touched the socket, `putrequest` with the query string masked,
|
|
36
|
+
`endheaders` with the body by size, `getresponse` annotated with
|
|
37
|
+
the status. A debugging aid rather than default instrumentation:
|
|
38
|
+
beneath a higher-level client's leaf event nothing records, so it
|
|
39
|
+
pairs with switching that client to `leaf = false`; standalone
|
|
40
|
+
http.client use records with no switch. One setting: `redact`
|
|
41
|
+
(query parameters masked by name on top of the built-in set). No
|
|
42
|
+
trace propagation at this layer; that belongs to the client above.
|
|
43
|
+
Supports Python 3.12 and later.
|
|
44
|
+
|
|
45
|
+
- xmlrpc.client (`xmlrpc.client`, standard library): every remote
|
|
46
|
+
call through a `ServerProxy` records as one external leaf on the
|
|
47
|
+
proxy's private `ServerProxy.__request` method, the one door they
|
|
48
|
+
all pass through, carrying the external
|
|
49
|
+
contract keys (method `POST`, url, host, port, path, and status:
|
|
50
|
+
200 for any parsed response, a `Fault` included, or the code a
|
|
51
|
+
`ProtocolError` carries) plus the RPC pair `system` (always
|
|
52
|
+
`xmlrpc`) and the method name as `operation`, which the
|
|
53
|
+
OpenTelemetry export maps to `rpc.system` and `rpc.method`, naming
|
|
54
|
+
the span by the operation.
|
|
55
|
+
The trace identity from `wrapture.trace_headers()` is added to
|
|
56
|
+
every request's headers, leaving one the application supplied
|
|
57
|
+
alone. Hosts and URLs are stripped of basic-auth userinfo,
|
|
58
|
+
arguments reduce to a count, results to a type and bodies to a
|
|
59
|
+
size. Two settings, both on by default: `leaf` (off to see the
|
|
60
|
+
transport event beneath each call, and the `http.client` wire
|
|
61
|
+
phases under that when enabled) and `propagate`. Supports Python
|
|
62
|
+
3.12 and later.
|
|
63
|
+
|
|
64
|
+
- xmlrpc.server (`xmlrpc.server`, standard library): every XML-RPC
|
|
65
|
+
POST a `SimpleXMLRPCServer` handles records as one request
|
|
66
|
+
boundary, a block labelled `xmlrpc.server` and categorised
|
|
67
|
+
`server` opened around the handler's `do_POST`, carrying `system`
|
|
68
|
+
(`xmlrpc`), the request method, path and client address and the
|
|
69
|
+
response status (200 with a marshalled response, a `Fault`
|
|
70
|
+
included; 404 for a path outside the handler's `rpc_paths`), and
|
|
71
|
+
joining the distributed trace an arriving `traceparent` header
|
|
72
|
+
carries, so both sides of a call between instrumented processes
|
|
73
|
+
share one trace id; the OpenTelemetry export reads the category as
|
|
74
|
+
a SERVER span named access-log style. Every dispatched
|
|
75
|
+
procedure records beneath it on
|
|
76
|
+
`SimpleXMLRPCDispatcher._dispatch`, annotated with the method name
|
|
77
|
+
as `operation`, a `system.multicall` nesting its sub-calls inside
|
|
78
|
+
the batch's own dispatch. Params reduce to a count and results to
|
|
79
|
+
a type; the headers only ever feed the join and are never
|
|
80
|
+
recorded. One setting: `join`, on by default. Supports Python 3.12
|
|
81
|
+
and later.
|
|
82
|
+
|
|
83
|
+
- wsgiref (`wsgiref.simple_server`, standard library): every
|
|
84
|
+
application the server is handed, through `make_server`,
|
|
85
|
+
`set_app` or a subclass, is wrapped in wrapture's recording WSGI
|
|
86
|
+
middleware at the server's own seam, `WSGIServer.get_app`, without
|
|
87
|
+
the application changing at all: one request tree per request,
|
|
88
|
+
named by the application's own module and qualname, carrying
|
|
89
|
+
method, path, the query with secrets masked, scheme, peer and the
|
|
90
|
+
status line, and joining the distributed trace an arriving
|
|
91
|
+
`traceparent` header carries. One boundary per request however
|
|
92
|
+
many layers record: an application already carrying its own
|
|
93
|
+
recording middleware (a Flask application the flask
|
|
94
|
+
instrumentation wrapped) passes the inner one through, and
|
|
95
|
+
framework annotations land on the one event. Removal restores
|
|
96
|
+
`get_app`, un-wrapping servers already running. Two settings:
|
|
97
|
+
`ignore_paths` (path globs whose requests record nothing at all)
|
|
98
|
+
and `redact` (query parameters masked by name on top of the
|
|
99
|
+
built-in set). Supports Python 3.12 and later.
|
|
100
|
+
|
|
101
|
+
- werkzeug (`werkzeug.serving`, werkzeug 3.x): every application
|
|
102
|
+
handed to werkzeug's development server, through `run_simple`,
|
|
103
|
+
`make_server`, a server class directly or Flask's `app.run()`, is
|
|
104
|
+
wrapped in wrapture's recording WSGI middleware as the server is
|
|
105
|
+
built (`BaseWSGIServer.__init__`, the one place the application is
|
|
106
|
+
handed over, werkzeug having no accessor on the request path):
|
|
107
|
+
one request tree per request, named by the application's own
|
|
108
|
+
module and qualname, carrying method, path, the query with
|
|
109
|
+
secrets masked, scheme, peer and the status line, and joining the
|
|
110
|
+
distributed trace an arriving `traceparent` header carries. One
|
|
111
|
+
boundary per request however many layers record, so it composes
|
|
112
|
+
with the flask instrumentation. Removal stops the wrapping for
|
|
113
|
+
servers built afterwards; a server built while instrumented keeps
|
|
114
|
+
its wrapper for its own lifetime. Two settings: `ignore_paths`
|
|
115
|
+
and `redact`, as on the wsgiref target. Supports werkzeug 3.x.
|
|
116
|
+
|
|
117
|
+
- uvicorn (`uvicorn`, uvicorn 0.30+): every application the server
|
|
118
|
+
loads, through `uvicorn.run()`, a `Server` built by hand or
|
|
119
|
+
gunicorn's `UvicornWorker`, is wrapped in wrapture's recording
|
|
120
|
+
ASGI middleware at the server's own seam, `Config.load`, without
|
|
121
|
+
the application changing at all: one request tree per request,
|
|
122
|
+
named by the application's own module and qualname, carrying
|
|
123
|
+
method, path, the query with secrets masked, scheme, peer, the
|
|
124
|
+
status line and the response's streaming shape, and joining the
|
|
125
|
+
distributed trace an arriving `traceparent` header carries. The
|
|
126
|
+
wrap lands inside uvicorn's own middlewares, around the
|
|
127
|
+
application itself, so the event is named by the application and
|
|
128
|
+
the recorded scope is the one the application sees (with proxy
|
|
129
|
+
headers on, uvicorn's default, the client and scheme are the
|
|
130
|
+
forwarded values). One boundary per request however many layers
|
|
131
|
+
record; websocket and lifespan traffic passes through untouched.
|
|
132
|
+
Removal restores `Config.load` for configs loaded afterwards; a
|
|
133
|
+
server already running keeps its wrapper for its own lifetime,
|
|
134
|
+
the werkzeug trade-off at the same kind of seam. Two settings:
|
|
135
|
+
`ignore_paths` and `redact`, as on the WSGI server targets.
|
|
136
|
+
Supports uvicorn 0.30 and later, below 1.0.
|
|
137
|
+
|
|
138
|
+
- sqlite3 (`sqlite3`, standard library): every query and transaction
|
|
139
|
+
boundary records as one database leaf. The connection and cursor
|
|
140
|
+
types are C types no patch can touch, so the `connect` factories
|
|
141
|
+
(both the `sqlite3` and `sqlite3.dbapi2` spellings) are bound and
|
|
142
|
+
each connection comes back wrapped in a recording proxy, cursors
|
|
143
|
+
included, every event labelled with the sqlite3 name it stands
|
|
144
|
+
for. Recorded: the connect, the execute family on cursors and the
|
|
145
|
+
connection's shortcut forms, `commit`, `rollback`, and the
|
|
146
|
+
connection's commit-or-rollback context manager, its exit saying
|
|
147
|
+
which it performed. Every event carries `system` (`sqlite`) and
|
|
148
|
+
`operation` (the SQL's leading keyword, or CONNECT, COMMIT,
|
|
149
|
+
ROLLBACK), the database contract the OpenTelemetry export maps to
|
|
150
|
+
`db.*` attributes. Bound parameters are never recorded; the SQL
|
|
151
|
+
text is recorded only behind the `statement` setting, off by
|
|
152
|
+
default, and reduces to its length otherwise. Fetching is not
|
|
153
|
+
recorded. Supports Python 3.12 and later.
|
|
154
|
+
|
|
155
|
+
- requests (`requests`, requests 2.31+): every request made through
|
|
156
|
+
the module-level helpers, `Session.request` or a `Session.send`
|
|
157
|
+
the application calls itself records as one external leaf on
|
|
158
|
+
`Session.send`, carrying the external category's contract keys
|
|
159
|
+
(method, URL without its query string or userinfo, host, port,
|
|
160
|
+
path, the query with secrets masked, and the status of whatever
|
|
161
|
+
came back: requests answers a 4xx or 5xx with a response, so an
|
|
162
|
+
error status is a status, and an exception is recorded only when
|
|
163
|
+
the exchange really failed). A redirect is one event named by the
|
|
164
|
+
URL asked for, and unless the caller streams, the event covers the
|
|
165
|
+
body download too. The trace identity from
|
|
166
|
+
`wrapture.trace_headers()` is added to every request's headers, a
|
|
167
|
+
redirect hop's copied headers carrying it onward and a header the
|
|
168
|
+
application set itself left alone. The request body is never
|
|
169
|
+
recorded and the response reduces to its type. Three settings, as
|
|
170
|
+
on the urllib target: `leaf`, `propagate` and `redact`. Supports
|
|
171
|
+
requests 2.31 and later in the 2.x line.
|
|
172
|
+
|
|
173
|
+
- FastAPI (`fastapi`, fastapi 0.110+): every request records as one
|
|
174
|
+
tree through wrapture's recording ASGI middleware, installed by
|
|
175
|
+
decorating `FastAPI.__call__`, the starlette target's seam one
|
|
176
|
+
class down, with a per-instance cache of this target's own so the
|
|
177
|
+
two boundaries stack rather than loop when both are applied, the
|
|
178
|
+
outer one recording. `APIRoute.handle` annotates the request event
|
|
179
|
+
with the route's path pattern (an including router's prefix folded
|
|
180
|
+
in) and name, needed in its own right because `APIRoute` builds
|
|
181
|
+
and can dispatch without touching the `Route` seams the starlette
|
|
182
|
+
target patches; `APIRoute.__init__` substitutes observed endpoint
|
|
183
|
+
functions labelled by the route's name, with dependency
|
|
184
|
+
injection, response models and OpenAPI generation reading the
|
|
185
|
+
proxy as the function it wraps, and `include_router()` re-handing
|
|
186
|
+
an observed endpoint back without stacking a second observation.
|
|
187
|
+
A validation failure records as its 422 and an unhandled
|
|
188
|
+
exception lands on the request event beside the 500. Two
|
|
189
|
+
settings: `ignore_paths` and `redact`, as on the starlette
|
|
190
|
+
target. Supports fastapi 0.110 and later, below 1.0.
|
|
191
|
+
|
|
192
|
+
- Starlette (`starlette`, starlette 0.47+): every request records
|
|
193
|
+
as one tree through wrapture's recording ASGI middleware,
|
|
194
|
+
installed by decorating `Starlette.__call__`, the application as a
|
|
195
|
+
server calls it, one cached wrapper per application instance. Once
|
|
196
|
+
routing matches, the request event is annotated with the route's
|
|
197
|
+
path pattern and name (`Route.handle` being the moment both are
|
|
198
|
+
known), the pattern being what the OpenTelemetry export maps to
|
|
199
|
+
`http.route`; a 404 gains no route keys, and a route inside a
|
|
200
|
+
`Mount` annotates the pattern it owns. Every endpoint function is
|
|
201
|
+
observed as its `Route` is built, labelled by the route's name,
|
|
202
|
+
sync and async endpoints alike; class-based endpoints, mounted
|
|
203
|
+
ASGI applications and `functools.partial` endpoints pass through
|
|
204
|
+
untouched. Unhandled exceptions need no extra machinery: starlette
|
|
205
|
+
answers 500 and re-raises, so the request event carries status and
|
|
206
|
+
exception together, while an `HTTPException` records as nothing
|
|
207
|
+
but its status. One boundary per request under an instrumented
|
|
208
|
+
server, the route annotation landing on it. Two settings:
|
|
209
|
+
`ignore_paths` and `redact`, as on the server targets. Supports
|
|
210
|
+
starlette 0.47 and later, below 2.0. The suites drive ASGI
|
|
211
|
+
applications in process through a new tests/asgi.py driver, the
|
|
212
|
+
ASGI counterpart of the WSGI one.
|
|
213
|
+
|
|
214
|
+
- httpx (`httpx`, httpx 0.27+): every request made through the
|
|
215
|
+
module-level helpers, a `Client` or an `AsyncClient` records as
|
|
216
|
+
one external leaf, on `Client.send` or its mirror
|
|
217
|
+
`AsyncClient.send` (the async event recording around the await),
|
|
218
|
+
carrying the same external contract keys as the requests target,
|
|
219
|
+
with the same statuses-not-exceptions rule and the same capture
|
|
220
|
+
policy (query masked, URL userinfo stripped, body never recorded,
|
|
221
|
+
response by type). httpx follows redirects only when asked:
|
|
222
|
+
unasked, the event carries the 3xx the caller saw; followed, the
|
|
223
|
+
hops resolve in a loop inside the one send, so a redirect is one
|
|
224
|
+
event whatever the leaf setting says, and the copied headers carry
|
|
225
|
+
the propagated trace identity on every hop. Unless the caller
|
|
226
|
+
streams, the event covers the body download too. Three settings,
|
|
227
|
+
as on the requests target: `leaf`, `propagate` and `redact`.
|
|
228
|
+
Supports httpx 0.27 and later, below 1.0.
|
|
229
|
+
|
|
230
|
+
- Jinja2 (`jinja2`, Jinja2 3.x): every render traced in all its
|
|
231
|
+
forms, sync, streamed and async, each annotated with the
|
|
232
|
+
template's own name; the loading pipeline
|
|
233
|
+
(`Environment._load_template` on every get_template,
|
|
234
|
+
`Environment.compile` inside a cold load) beneath it, behind a
|
|
235
|
+
`loading` switch; every event named by its patched location as
|
|
236
|
+
`module:qualname`; and the render context, output and template
|
|
237
|
+
source kept out of capture or truncated.
|
|
238
|
+
|
|
239
|
+
- Flask (`flask`, Flask 3.x): every request records as one tree
|
|
240
|
+
through the recording WSGI middleware installed at construction,
|
|
241
|
+
annotated with the matched route pattern and endpoint (the route
|
|
242
|
+
is what wrapture's OpenTelemetry export names the span by, as
|
|
243
|
+
`http.route`); every view
|
|
244
|
+
function is observed as it registers and labelled by its endpoint
|
|
245
|
+
(blueprints and `MethodView`s included); lifecycle callbacks and
|
|
246
|
+
error handlers are observed however they register; and failures
|
|
247
|
+
are noted against the request, whether Flask answered 500 or a
|
|
248
|
+
registered handler absorbed a real exception (an `HTTPException`
|
|
249
|
+
is control flow and is not noted); and template rendering records
|
|
250
|
+
beneath the view that asked for it, named by the spelling the call
|
|
251
|
+
took (`flask:render_template` or
|
|
252
|
+
`flask.templating:render_template`), capturing the template name
|
|
253
|
+
while the render context and output stay out of capture. Three
|
|
254
|
+
settings switch the optional layers, all on by default:
|
|
255
|
+
`lifecycle`, `handled_errors` and `templates`; two more shape what
|
|
256
|
+
a recorded request carries: `ignore_paths` (path globs whose
|
|
257
|
+
requests record nothing at all, request and everything beneath it
|
|
258
|
+
alike) and `redact`
|
|
259
|
+
(query parameters masked by name on top of the built-in sensitive
|
|
260
|
+
set).
|
|
261
|
+
|
|
262
|
+
- aiohttp client (`aiohttp.client`, aiohttp 3.10+): every outbound
|
|
263
|
+
request made through a `ClientSession`, by the verb helpers,
|
|
264
|
+
`session.request` or a streamed `async with`, records as one
|
|
265
|
+
external leaf on `ClientSession._request`, the one coroutine they
|
|
266
|
+
all pass through, carrying the external category's contract keys
|
|
267
|
+
(method, URL without its query string or userinfo, host, port,
|
|
268
|
+
path, the query with secrets masked, and the status whether
|
|
269
|
+
returned or, for a real connection failure, absent). A followed
|
|
270
|
+
redirect is one event named by the URL asked for: aiohttp resolves
|
|
271
|
+
the hops in a loop inside the one call. The coroutine returns when
|
|
272
|
+
the response headers are in, so the event covers the exchange to
|
|
273
|
+
the response's start, not the body read afterwards. The trace
|
|
274
|
+
identity from `wrapture.trace_headers()` is added to each request's
|
|
275
|
+
headers, leaving a header the application set alone, and aiohttp
|
|
276
|
+
carries them onto every redirect hop, so both sides of a call
|
|
277
|
+
between instrumented processes share one trace id. The request body
|
|
278
|
+
is never recorded and the call's arguments are not captured (the
|
|
279
|
+
signature is wide, and the method and URL are already the event's
|
|
280
|
+
contract keys); query supplied through `params=` rather than in the
|
|
281
|
+
URL is not folded into the recording. Three settings, `leaf` and
|
|
282
|
+
`propagate` on by default and `redact`, as on the other external
|
|
283
|
+
clients. Supports aiohttp 3.10 and later, below 4.
|
|
284
|
+
|
|
285
|
+
- aiohttp (`aiohttp.web`, aiohttp 3.10+): every request an aiohttp
|
|
286
|
+
server handles records as one `server`-categorised request
|
|
287
|
+
boundary opened around the application's own dispatch
|
|
288
|
+
(`Application._handle`, so a sub-application's requests land in
|
|
289
|
+
the one boundary too), carrying method, path, scheme, peer and the
|
|
290
|
+
query with secrets masked, annotated once dispatch has run with
|
|
291
|
+
the matched route's canonical pattern and name (the pattern is
|
|
292
|
+
what the OpenTelemetry export names the SERVER span by, and maps
|
|
293
|
+
to `http.route`) and with the response's status: an
|
|
294
|
+
`HTTPException` is control flow and records as the status it
|
|
295
|
+
answers, while a real failure records as the exception, the
|
|
296
|
+
protocol answering its 500 on its own. The boundary joins the
|
|
297
|
+
distributed trace an arriving `traceparent` header carries, and
|
|
298
|
+
every handler function is observed as its route registers, so each
|
|
299
|
+
dispatch records the handler's call beneath the boundary, labelled
|
|
300
|
+
by the route's name when one was given; class-based views register
|
|
301
|
+
untouched and are named on the boundary only. Three settings:
|
|
302
|
+
`ignore_paths` (path globs whose requests record nothing at all,
|
|
303
|
+
the handler included, the filter evaluated by hand at the block
|
|
304
|
+
boundary through `RequestFilter.matches()`), `join` (on by
|
|
305
|
+
default) and `redact` (query parameters masked by name on top of
|
|
306
|
+
the built-in set). Supports aiohttp 3.10 and later, below 4.
|
|
307
|
+
|
|
308
|
+
- SQLAlchemy (`sqlalchemy`, SQLAlchemy 1.4+): every statement an
|
|
309
|
+
engine executes records as one database leaf at the dialect seam
|
|
310
|
+
every driver sits behind (`DefaultDialect.do_execute` and its
|
|
311
|
+
executemany and no-params siblings, which Core and ORM, sync and
|
|
312
|
+
async engine alike all funnel into; the driver dialects that
|
|
313
|
+
override `do_executemany` with a fast path, psycopg2's and its
|
|
314
|
+
kin, are bound in their own right as their modules load). Each
|
|
315
|
+
event carries the database contract keys `system` (the dialect's
|
|
316
|
+
name) and `operation` (the SQL's leading keyword), plus the
|
|
317
|
+
database, host and port from the engine's URL. The connections
|
|
318
|
+
the pool really opens record as `CONNECT` events with none of
|
|
319
|
+
their arguments captured (they are the driver's credentials), and
|
|
320
|
+
the transaction boundaries record on `Connection`'s commit and
|
|
321
|
+
rollback implementations, the one door every real transaction end
|
|
322
|
+
passes through, which the pool's reset-on-return rollbacks do not
|
|
323
|
+
use. Bound parameters are never recorded; the SQL text reduces to
|
|
324
|
+
its length unless the `statement` setting is on. With an
|
|
325
|
+
instrumented driver beneath (sqlite3), the default `leaf = true`
|
|
326
|
+
keeps the driver's events out of the tree and `leaf = false`
|
|
327
|
+
nests them beneath each statement. Supports SQLAlchemy 1.4 and
|
|
328
|
+
later, below 3.
|
|
329
|
+
|
|
330
|
+
- gRPC (`grpc`, grpcio 1.76+): one instrumentation covers both
|
|
331
|
+
halves, riding gRPC's own interceptor machinery injected at the
|
|
332
|
+
public factories: `insecure_channel` and `secure_channel` hand
|
|
333
|
+
their channel back wrapped with a client interceptor covering all
|
|
334
|
+
four call shapes, and `server()` gets a server interceptor
|
|
335
|
+
prepended. Every RPC a channel makes records as one external leaf
|
|
336
|
+
carrying `system`, `service` and `operation` split from the
|
|
337
|
+
method path (mapped to `rpc.system`, `rpc.service` and
|
|
338
|
+
`rpc.method` by the OpenTelemetry export) plus the channel's host
|
|
339
|
+
and port; an error code is a status, not an exception, and a
|
|
340
|
+
streamed response records the call rather than its consumption,
|
|
341
|
+
the database targets' model. Every RPC a server handles records
|
|
342
|
+
as one `server` boundary spanning the handler's run, a streaming
|
|
343
|
+
handler's whole generator body included, joining the distributed
|
|
344
|
+
trace the metadata carries; an `abort()` is control flow recorded
|
|
345
|
+
as its code with the boundary clean, an escaped exception the
|
|
346
|
+
failure it is, beside the UNKNOWN gRPC answers. The trace
|
|
347
|
+
identity is added to each outgoing call's metadata, one the
|
|
348
|
+
application set left alone. Payloads and metadata values are
|
|
349
|
+
never recorded. Four settings, all on by default: `client`,
|
|
350
|
+
`server`, `propagate` and `join`. grpc.aio is not yet covered.
|
|
351
|
+
Supports grpcio 1.76 and later, below 2.
|
|
352
|
+
|
|
353
|
+
- urllib3 (`urllib3`, urllib3 1.26+): every request made through a
|
|
354
|
+
pool manager, a connection pool or the module-level `urllib3.request`
|
|
355
|
+
records as one external leaf on `urlopen`. The two doors a request
|
|
356
|
+
can enter by (`PoolManager.urlopen`, the redirect-following entry,
|
|
357
|
+
and `HTTPConnectionPool.urlopen` beneath it, the binding on it
|
|
358
|
+
covering `HTTPSConnectionPool`) share one depth count, so a
|
|
359
|
+
request is one event whichever door it entered by, with the
|
|
360
|
+
manager's delegation to a pool, a followed redirect and a retry
|
|
361
|
+
folded in. It carries the external contract keys read from the
|
|
362
|
+
pool instance and the URL together (method, URL without its query
|
|
363
|
+
or userinfo, host, port, path, and the query with secrets masked),
|
|
364
|
+
and the status whether returned or, for a real failure, absent
|
|
365
|
+
with the exception recorded instead. The trace identity from
|
|
366
|
+
`wrapture.trace_headers()` is added to each request's headers,
|
|
367
|
+
hop by hop, leaving a header the application set alone; the body
|
|
368
|
+
is never recorded and the response reduces to its type. Beneath
|
|
369
|
+
the requests leaf urllib3 stays silent (requests does its wire
|
|
370
|
+
work through it); standalone, or with the requests leaf off, it
|
|
371
|
+
records its own. Three settings: `leaf` and `propagate`, both on
|
|
372
|
+
by default, and `redact`. Supports urllib3 1.26 and later, below
|
|
373
|
+
3.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wrapture-instrumentation
|
|
3
|
-
Version: 1.0.0.
|
|
3
|
+
Version: 1.0.0.dev8
|
|
4
4
|
Summary: Instrumentation for common Python packages, applied through wrapture.
|
|
5
5
|
Author-email: Graham Dumpleton <Graham.Dumpleton@gmail.com>
|
|
6
6
|
License-Expression: BSD-2-Clause
|
|
@@ -17,7 +17,7 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
|
17
17
|
Requires-Python: >=3.12
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
-
Requires-Dist: wrapture>=1.0.
|
|
20
|
+
Requires-Dist: wrapture>=1.0.0a19
|
|
21
21
|
Dynamic: license-file
|
|
22
22
|
|
|
23
23
|
# wrapture-instrumentation
|
|
@@ -94,15 +94,25 @@ $ python -m wrapture.tools instrumentation --toml
|
|
|
94
94
|
|
|
95
95
|
| Target | Supported versions | Records | Settings |
|
|
96
96
|
| ------ | ------------------ | ------- | -------- |
|
|
97
|
+
| [`aiohttp.client`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/aiohttp_client/README.md) | aiohttp 3.10+ (3.x) | Every outbound request through a `ClientSession` (the verb helpers, `session.request`, a streamed `async with`) as one external leaf on `_request` carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); a followed redirect one event resolved inside it; the trace identity propagated hop by hop; the query and any URL credentials masked, the body never recorded. | `leaf`, `propagate`, `redact` |
|
|
98
|
+
| [`aiohttp.web`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/aiohttp_web/README.md) | aiohttp 3.10+ (3.x) | Every request an aiohttp server handles as one `server`-categorised request boundary carrying method, path, scheme, peer and redacted query, annotated with the matched route pattern (a sub-application's prefix folded in, exported as `http.route`) and status (an `HTTPException` is its status, not a failure), joining the trace a `traceparent` header carries; every registered handler function observed as its route is built and recorded beneath the boundary, labelled by the route's name. | `ignore_paths`, `join`, `redact` |
|
|
99
|
+
| [`fastapi`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/fastapi/README.md) | fastapi 0.110+ (below 1.0) | Every request as one tree through the recording ASGI middleware on the application's own `__call__`, annotated with the matched route pattern (router prefixes folded in) and name, the pattern exported as `http.route`; every endpoint function observed as its `APIRoute` is built, labelled by the route's name, dependency injection and response models undisturbed; validation failures record as their 422, unhandled failures on the request event beside the 500. | `ignore_paths`, `redact` |
|
|
97
100
|
| [`flask`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/flask/README.md) | Flask 3.x | Every request as one tree, annotated with route and endpoint; every view observed and labelled by endpoint; template renders beneath their views; handled and unhandled failures noted on the request. | `ignore_paths`, `redact`, `lifecycle`, `handled_errors`, `templates` |
|
|
101
|
+
| [`grpc`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/rpc/grpc/README.md) | grpcio 1.76+ (1.x) | Every RPC a channel makes, all four call shapes, as one external leaf through an injected client interceptor, carrying the rpc system, service and method, host, port and status code (an error code is a status, not an exception; a streamed response records the call, its consumption deliberately not tracked); every RPC a server handles as one `server` boundary through an injected server interceptor spanning the handler's run (a streaming handler's whole body), joining the trace the metadata carries; an abort is its code with the boundary clean, an escaped exception the failure it is; payloads and metadata never recorded. | `client`, `server`, `propagate`, `join` |
|
|
102
|
+
| [`http.client`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/http_client/README.md) | Python 3.12+ (standard library) | The wire phases of each exchange (connect where the socket really opens, the request line with its query masked, headers and body out by size, the response wait with its status) as plain events. A debugging aid: beneath an instrumented higher-level client nothing records until that client is switched to `leaf = false`. | `redact` |
|
|
103
|
+
| [`httpx`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/httpx/README.md) | httpx 0.27+ (below 1.0) | Every request through the module-level helpers, a `Client` or an `AsyncClient`, sync and async alike, as one external leaf on `send` carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); a followed redirect one event resolved inside it; the trace identity propagated hop by hop; the query and any URL credentials masked, the body never recorded. | `leaf`, `propagate`, `redact` |
|
|
98
104
|
| [`jinja2`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/template/jinja2/README.md) | Jinja2 3.x | Every render traced in all its forms (sync, async, streamed), annotated with the template name; the loading and compile pipeline beneath it; context and output kept out of capture. | `loading` |
|
|
105
|
+
| [`requests`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/requests/README.md) | requests 2.31+ (2.x) | Every request through the module-level helpers, `Session.request` or `Session.send` itself as one external leaf carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); a redirect one leaf named by the URL asked for; the trace identity propagated hop by hop; the query and any URL credentials masked, the body never recorded. | `leaf`, `propagate`, `redact` |
|
|
106
|
+
| [`sqlalchemy`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/database/sqlalchemy/README.md) | SQLAlchemy 1.4+ (below 3.0) | Every statement an engine executes, Core and ORM, sync and async alike, as one database leaf at the dialect seam every driver sits behind, carrying the system, the SQL's leading keyword as the operation and the database; the connections the pool really opens and the transaction boundaries recorded the same way, the pool's own reset rollbacks excluded; bound parameters and credentials never recorded, the SQL text only behind a setting. | `leaf`, `statement` |
|
|
107
|
+
| [`sqlite3`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/database/sqlite3/README.md) | Python 3.12+ (standard library) | Every query and transaction boundary as one database leaf, through recording proxies around the connections `connect` hands out, carrying the system and the SQL's leading keyword as the operation; bound parameters never recorded, the SQL text only behind a setting. | `statement` |
|
|
108
|
+
| [`starlette`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/starlette/README.md) | starlette 0.47+ (below 2.0) | Every request as one tree through the recording ASGI middleware on the application's own `__call__`, annotated with the matched route pattern and name (the pattern is what the OpenTelemetry export names the span by, as `http.route`); every endpoint function observed as its route is built, labelled by the route's name, sync and async alike; unhandled failures on the request event beside the 500. | `ignore_paths`, `redact` |
|
|
99
109
|
| [`urllib.request`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/urllib_request/README.md) | Python 3.12+ (standard library) | Every request through `urllib.request` as one external leaf carrying method, URL, host, port, path, query and status; the trace identity propagated in its headers; the query recorded with secrets masked, the body and response kept out of capture. | `leaf`, `propagate`, `redact` |
|
|
100
|
-
| [`
|
|
110
|
+
| [`urllib3`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/urllib3/README.md) | urllib3 1.26+ (below 3.0) | Every request through a pool manager, a connection pool or the module-level helper as one external leaf on `urlopen` (both doors sharing one depth count, so a redirect, a retry and the manager's delegation to a pool fold into it) carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); the trace identity propagated in the headers; the query and any URL credentials masked, the body never recorded. Beneath the requests leaf it stays silent; standalone it records its own. | `leaf`, `propagate`, `redact` |
|
|
111
|
+
| [`uvicorn`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/uvicorn/README.md) | uvicorn 0.30+ (below 1.0) | Every application the server loads wrapped in the recording ASGI middleware at uvicorn's own seam, inside its proxy-headers middleware: one request tree per request, named by the application, with method, path, redacted query, status and streaming shape, joining the trace a `traceparent` header carries; an application's own recording middleware still records one boundary per request. | `ignore_paths`, `redact` |
|
|
112
|
+
| [`werkzeug.serving`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/werkzeug_serving/README.md) | werkzeug 3.x | Every application handed to werkzeug's development server (Flask's `app.run()` included) wrapped in the recording WSGI middleware as the server is built: one request tree per request with method, path, redacted query and status, joining the trace a `traceparent` header carries; a framework's own recording middleware still records one boundary per request. | `ignore_paths`, `redact` |
|
|
113
|
+
| [`wsgiref.simple_server`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/wsgiref_simple_server/README.md) | Python 3.12+ (standard library) | Every application the server is handed wrapped in the recording WSGI middleware at the server's own seam: one request tree per request with method, path, redacted query and status, joining the trace a `traceparent` header carries; an application already recording (a framework's own middleware) still records one boundary per request. | `ignore_paths`, `redact` |
|
|
101
114
|
| [`xmlrpc.client`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/xmlrpc_client/README.md) | Python 3.12+ (standard library) | Every remote call through a `ServerProxy` as one external leaf carrying the RPC system and method name, URL, host, port, path and status (a `Fault` is a 200, a `ProtocolError` its code); the trace identity propagated in its headers; credentials, arguments, results and bodies kept out of capture. | `leaf`, `propagate` |
|
|
102
115
|
| [`xmlrpc.server`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/xmlrpc_server/README.md) | Python 3.12+ (standard library) | Every XML-RPC POST a `SimpleXMLRPCServer` handles as one `server`-categorised request boundary carrying method, path, client and status, joining the distributed trace an arriving `traceparent` header carries; each dispatched procedure beneath it with the method name as `operation`, multicall sub-calls nested; params and results reduced to counts and types. | `join` |
|
|
103
|
-
| [`wsgiref.simple_server`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/wsgiref_simple_server/README.md) | Python 3.12+ (standard library) | Every application the server is handed wrapped in the recording WSGI middleware at the server's own seam: one request tree per request with method, path, redacted query and status, joining the trace a `traceparent` header carries; an application already recording (a framework's own middleware) still records one boundary per request. | `ignore_paths`, `redact` |
|
|
104
|
-
| [`werkzeug.serving`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/werkzeug_serving/README.md) | werkzeug 3.x | Every application handed to werkzeug's development server (Flask's `app.run()` included) wrapped in the recording WSGI middleware as the server is built: one request tree per request with method, path, redacted query and status, joining the trace a `traceparent` header carries; a framework's own recording middleware still records one boundary per request. | `ignore_paths`, `redact` |
|
|
105
|
-
| [`sqlite3`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/database/sqlite3/README.md) | Python 3.12+ (standard library) | Every query and transaction boundary as one database leaf, through recording proxies around the connections `connect` hands out, carrying the system and the SQL's leading keyword as the operation; bound parameters never recorded, the SQL text only behind a setting. | `statement` |
|
|
106
116
|
|
|
107
117
|
The entry point name is the config's `name`; the table summarizes
|
|
108
118
|
each instrumentation, and the linked per-target README is its full
|
|
@@ -133,6 +143,9 @@ wrapture the instrumentation mostly uses:
|
|
|
133
143
|
|
|
134
144
|
- `task/`: task queues. `messaging/`: brokers and their clients.
|
|
135
145
|
|
|
146
|
+
- `rpc/`: RPC frameworks whose one package covers both the client
|
|
147
|
+
and the server side.
|
|
148
|
+
|
|
136
149
|
- `server/`: servers handling inbound requests, WSGI and ASGI
|
|
137
150
|
servers included.
|
|
138
151
|
|
|
@@ -72,15 +72,25 @@ $ python -m wrapture.tools instrumentation --toml
|
|
|
72
72
|
|
|
73
73
|
| Target | Supported versions | Records | Settings |
|
|
74
74
|
| ------ | ------------------ | ------- | -------- |
|
|
75
|
+
| [`aiohttp.client`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/aiohttp_client/README.md) | aiohttp 3.10+ (3.x) | Every outbound request through a `ClientSession` (the verb helpers, `session.request`, a streamed `async with`) as one external leaf on `_request` carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); a followed redirect one event resolved inside it; the trace identity propagated hop by hop; the query and any URL credentials masked, the body never recorded. | `leaf`, `propagate`, `redact` |
|
|
76
|
+
| [`aiohttp.web`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/aiohttp_web/README.md) | aiohttp 3.10+ (3.x) | Every request an aiohttp server handles as one `server`-categorised request boundary carrying method, path, scheme, peer and redacted query, annotated with the matched route pattern (a sub-application's prefix folded in, exported as `http.route`) and status (an `HTTPException` is its status, not a failure), joining the trace a `traceparent` header carries; every registered handler function observed as its route is built and recorded beneath the boundary, labelled by the route's name. | `ignore_paths`, `join`, `redact` |
|
|
77
|
+
| [`fastapi`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/fastapi/README.md) | fastapi 0.110+ (below 1.0) | Every request as one tree through the recording ASGI middleware on the application's own `__call__`, annotated with the matched route pattern (router prefixes folded in) and name, the pattern exported as `http.route`; every endpoint function observed as its `APIRoute` is built, labelled by the route's name, dependency injection and response models undisturbed; validation failures record as their 422, unhandled failures on the request event beside the 500. | `ignore_paths`, `redact` |
|
|
75
78
|
| [`flask`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/flask/README.md) | Flask 3.x | Every request as one tree, annotated with route and endpoint; every view observed and labelled by endpoint; template renders beneath their views; handled and unhandled failures noted on the request. | `ignore_paths`, `redact`, `lifecycle`, `handled_errors`, `templates` |
|
|
79
|
+
| [`grpc`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/rpc/grpc/README.md) | grpcio 1.76+ (1.x) | Every RPC a channel makes, all four call shapes, as one external leaf through an injected client interceptor, carrying the rpc system, service and method, host, port and status code (an error code is a status, not an exception; a streamed response records the call, its consumption deliberately not tracked); every RPC a server handles as one `server` boundary through an injected server interceptor spanning the handler's run (a streaming handler's whole body), joining the trace the metadata carries; an abort is its code with the boundary clean, an escaped exception the failure it is; payloads and metadata never recorded. | `client`, `server`, `propagate`, `join` |
|
|
80
|
+
| [`http.client`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/http_client/README.md) | Python 3.12+ (standard library) | The wire phases of each exchange (connect where the socket really opens, the request line with its query masked, headers and body out by size, the response wait with its status) as plain events. A debugging aid: beneath an instrumented higher-level client nothing records until that client is switched to `leaf = false`. | `redact` |
|
|
81
|
+
| [`httpx`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/httpx/README.md) | httpx 0.27+ (below 1.0) | Every request through the module-level helpers, a `Client` or an `AsyncClient`, sync and async alike, as one external leaf on `send` carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); a followed redirect one event resolved inside it; the trace identity propagated hop by hop; the query and any URL credentials masked, the body never recorded. | `leaf`, `propagate`, `redact` |
|
|
76
82
|
| [`jinja2`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/template/jinja2/README.md) | Jinja2 3.x | Every render traced in all its forms (sync, async, streamed), annotated with the template name; the loading and compile pipeline beneath it; context and output kept out of capture. | `loading` |
|
|
83
|
+
| [`requests`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/requests/README.md) | requests 2.31+ (2.x) | Every request through the module-level helpers, `Session.request` or `Session.send` itself as one external leaf carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); a redirect one leaf named by the URL asked for; the trace identity propagated hop by hop; the query and any URL credentials masked, the body never recorded. | `leaf`, `propagate`, `redact` |
|
|
84
|
+
| [`sqlalchemy`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/database/sqlalchemy/README.md) | SQLAlchemy 1.4+ (below 3.0) | Every statement an engine executes, Core and ORM, sync and async alike, as one database leaf at the dialect seam every driver sits behind, carrying the system, the SQL's leading keyword as the operation and the database; the connections the pool really opens and the transaction boundaries recorded the same way, the pool's own reset rollbacks excluded; bound parameters and credentials never recorded, the SQL text only behind a setting. | `leaf`, `statement` |
|
|
85
|
+
| [`sqlite3`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/database/sqlite3/README.md) | Python 3.12+ (standard library) | Every query and transaction boundary as one database leaf, through recording proxies around the connections `connect` hands out, carrying the system and the SQL's leading keyword as the operation; bound parameters never recorded, the SQL text only behind a setting. | `statement` |
|
|
86
|
+
| [`starlette`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/framework/starlette/README.md) | starlette 0.47+ (below 2.0) | Every request as one tree through the recording ASGI middleware on the application's own `__call__`, annotated with the matched route pattern and name (the pattern is what the OpenTelemetry export names the span by, as `http.route`); every endpoint function observed as its route is built, labelled by the route's name, sync and async alike; unhandled failures on the request event beside the 500. | `ignore_paths`, `redact` |
|
|
77
87
|
| [`urllib.request`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/urllib_request/README.md) | Python 3.12+ (standard library) | Every request through `urllib.request` as one external leaf carrying method, URL, host, port, path, query and status; the trace identity propagated in its headers; the query recorded with secrets masked, the body and response kept out of capture. | `leaf`, `propagate`, `redact` |
|
|
78
|
-
| [`
|
|
88
|
+
| [`urllib3`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/urllib3/README.md) | urllib3 1.26+ (below 3.0) | Every request through a pool manager, a connection pool or the module-level helper as one external leaf on `urlopen` (both doors sharing one depth count, so a redirect, a retry and the manager's delegation to a pool fold into it) carrying method, URL, host, port, path, query and status (an error status is a status, not an exception); the trace identity propagated in the headers; the query and any URL credentials masked, the body never recorded. Beneath the requests leaf it stays silent; standalone it records its own. | `leaf`, `propagate`, `redact` |
|
|
89
|
+
| [`uvicorn`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/uvicorn/README.md) | uvicorn 0.30+ (below 1.0) | Every application the server loads wrapped in the recording ASGI middleware at uvicorn's own seam, inside its proxy-headers middleware: one request tree per request, named by the application, with method, path, redacted query, status and streaming shape, joining the trace a `traceparent` header carries; an application's own recording middleware still records one boundary per request. | `ignore_paths`, `redact` |
|
|
90
|
+
| [`werkzeug.serving`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/werkzeug_serving/README.md) | werkzeug 3.x | Every application handed to werkzeug's development server (Flask's `app.run()` included) wrapped in the recording WSGI middleware as the server is built: one request tree per request with method, path, redacted query and status, joining the trace a `traceparent` header carries; a framework's own recording middleware still records one boundary per request. | `ignore_paths`, `redact` |
|
|
91
|
+
| [`wsgiref.simple_server`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/wsgiref_simple_server/README.md) | Python 3.12+ (standard library) | Every application the server is handed wrapped in the recording WSGI middleware at the server's own seam: one request tree per request with method, path, redacted query and status, joining the trace a `traceparent` header carries; an application already recording (a framework's own middleware) still records one boundary per request. | `ignore_paths`, `redact` |
|
|
79
92
|
| [`xmlrpc.client`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/external/xmlrpc_client/README.md) | Python 3.12+ (standard library) | Every remote call through a `ServerProxy` as one external leaf carrying the RPC system and method name, URL, host, port, path and status (a `Fault` is a 200, a `ProtocolError` its code); the trace identity propagated in its headers; credentials, arguments, results and bodies kept out of capture. | `leaf`, `propagate` |
|
|
80
93
|
| [`xmlrpc.server`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/xmlrpc_server/README.md) | Python 3.12+ (standard library) | Every XML-RPC POST a `SimpleXMLRPCServer` handles as one `server`-categorised request boundary carrying method, path, client and status, joining the distributed trace an arriving `traceparent` header carries; each dispatched procedure beneath it with the method name as `operation`, multicall sub-calls nested; params and results reduced to counts and types. | `join` |
|
|
81
|
-
| [`wsgiref.simple_server`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/wsgiref_simple_server/README.md) | Python 3.12+ (standard library) | Every application the server is handed wrapped in the recording WSGI middleware at the server's own seam: one request tree per request with method, path, redacted query and status, joining the trace a `traceparent` header carries; an application already recording (a framework's own middleware) still records one boundary per request. | `ignore_paths`, `redact` |
|
|
82
|
-
| [`werkzeug.serving`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/server/werkzeug_serving/README.md) | werkzeug 3.x | Every application handed to werkzeug's development server (Flask's `app.run()` included) wrapped in the recording WSGI middleware as the server is built: one request tree per request with method, path, redacted query and status, joining the trace a `traceparent` header carries; a framework's own recording middleware still records one boundary per request. | `ignore_paths`, `redact` |
|
|
83
|
-
| [`sqlite3`](https://github.com/GrahamDumpleton/wrapture-instrumentation/blob/develop/src/wrapture_instrumentation/database/sqlite3/README.md) | Python 3.12+ (standard library) | Every query and transaction boundary as one database leaf, through recording proxies around the connections `connect` hands out, carrying the system and the SQL's leading keyword as the operation; bound parameters never recorded, the SQL text only behind a setting. | `statement` |
|
|
84
94
|
|
|
85
95
|
The entry point name is the config's `name`; the table summarizes
|
|
86
96
|
each instrumentation, and the linked per-target README is its full
|
|
@@ -111,6 +121,9 @@ wrapture the instrumentation mostly uses:
|
|
|
111
121
|
|
|
112
122
|
- `task/`: task queues. `messaging/`: brokers and their clients.
|
|
113
123
|
|
|
124
|
+
- `rpc/`: RPC frameworks whose one package covers both the client
|
|
125
|
+
and the server side.
|
|
126
|
+
|
|
114
127
|
- `server/`: servers handling inbound requests, WSGI and ASGI
|
|
115
128
|
servers included.
|
|
116
129
|
|
|
@@ -23,8 +23,8 @@ The directory has two levels:
|
|
|
23
23
|
name, and a check that the installed target satisfies the class's
|
|
24
24
|
`supports` range.
|
|
25
25
|
|
|
26
|
-
Shared helpers live in [tests/conftest.py](tests/conftest.py)
|
|
27
|
-
[tests/wsgi.py](tests/wsgi.py).
|
|
26
|
+
Shared helpers live in [tests/conftest.py](tests/conftest.py),
|
|
27
|
+
[tests/wsgi.py](tests/wsgi.py) and [tests/asgi.py](tests/asgi.py).
|
|
28
28
|
|
|
29
29
|
## The WSGI driver
|
|
30
30
|
|
|
@@ -40,7 +40,11 @@ the driver makes that moment explicit: `request(app, "GET", "/path")`
|
|
|
40
40
|
reads and closes for the common case, and `consume=False` hands back
|
|
41
41
|
the response with its body unconsumed so a test can check the
|
|
42
42
|
request is still open, then `read()` and `close()` it. The same
|
|
43
|
-
driver serves every WSGI target.
|
|
43
|
+
driver serves every WSGI target. Its ASGI counterpart in
|
|
44
|
+
tests/asgi.py plays the server's side of the ASGI 3 HTTP protocol
|
|
45
|
+
the same way, awaiting the application to completion under
|
|
46
|
+
asyncio.run so the request event has closed when it returns; it
|
|
47
|
+
serves the ASGI framework and server suites.
|
|
44
48
|
|
|
45
49
|
## Running the tests
|
|
46
50
|
|