diff --git a/connect/eaas/logging.py b/connect/eaas/logging.py index dbbf828..ad36a03 100644 --- a/connect/eaas/logging.py +++ b/connect/eaas/logging.py @@ -1,3 +1,5 @@ +import json + from logzio.handler import LogzioHandler @@ -10,3 +12,48 @@ def extra_fields(self, message): extra_fields = super().extra_fields(message) extra_fields.update(self.default_extra_fields) return extra_fields + + +class RequestLogger: + + def __init__(self, logger): + self.logger = logger + + def log_request(self, method, url, kwargs): + other_args = {k: v for k, v in kwargs.items() if k not in ('headers', 'json', 'params')} + + if 'params' in kwargs: + url += '&' if '?' in url else '?' + url += '&'.join([f'{k}={v}' for k, v in kwargs['params'].items()]) + + lines = [ + '--- HTTP Request ---', + f'{method.upper()} {url} {other_args if other_args else ""}', + ] + + if 'headers' in kwargs: + for k, v in kwargs['headers'].items(): + lines.append(f'{k}: {v}') + + if 'json' in kwargs: + lines.append(json.dumps(kwargs['json'], indent=4)) + + lines.append('') + self.logger.debug('\n'.join(lines)) + + def log_response(self, response): + reason = response.raw.reason if getattr(response, 'raw', None) else response.reason_phrase + lines = [ + '--- HTTP Response ---', + f'{response.status_code} {reason}', + ] + + for k, v in response.headers.items(): + lines.append(f'{k}: {v}') + + if response.headers.get('Content-Type', None) == 'application/json': + lines.append(json.dumps(response.json(), indent=4)) + + lines.append('') + + self.logger.debug('\n'.join(lines)) diff --git a/connect/eaas/worker.py b/connect/eaas/worker.py index 1df1c77..633c2ef 100644 --- a/connect/eaas/worker.py +++ b/connect/eaas/worker.py @@ -23,7 +23,7 @@ get_extension_class, get_extension_type, ) -from connect.eaas.logging import ExtensionLogHandler +from connect.eaas.logging import ExtensionLogHandler, RequestLogger from connect.eaas.manager import TasksManager @@ -103,6 +103,9 @@ def get_client(self): self.api_key, endpoint=f'https://{self.api_address}/public/v1', use_specs=False, + logger=RequestLogger( + self.get_extension_logger(self.logging_api_key), + ), ) def get_extension_logger(self, token): @@ -140,7 +143,12 @@ def ensure_tasks_manager_running(self): self.start_tasks_manager() def get_url(self): - return f'{self.base_ws_url}/{self.environment_id}/{self.instance_id}' + running_tasks = ( + self.tasks_manager.running_tasks + if self.tasks_manager else 0 + ) + url = f'{self.base_ws_url}/{self.environment_id}/{self.instance_id}' + return f'{url}?running_tasks={running_tasks}' def get_extension(self): return self.extension_class( @@ -224,6 +232,7 @@ async def configuration(self, data): if data.environment_type: self.environment_type = data.environment_type if data.log_level: + logger.info(f'Change extesion logger level to {data.log_level}') logging.getLogger('eaas.extension').setLevel( getattr(logging, data.log_level), ) @@ -267,5 +276,5 @@ async def start(self): logger.info('Control worker stopped') def stop(self): - logger.info('Stopping control worker.....') + logger.info('Stopping control worker...') self.run_event.clear() diff --git a/poetry.lock b/poetry.lock index 29895a4..36c65d8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -6,9 +6,26 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "anyio" +version = "3.2.1" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "main" +optional = false +python-versions = ">=3.6.2" + +[package.dependencies] +idna = ">=2.8" +sniffio = ">=1.1" + +[package.extras] +doc = ["sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] +test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=6.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] +trio = ["trio (>=0.16)"] + [[package]] name = "asgiref" -version = "3.3.4" +version = "3.4.1" description = "ASGI specs, helper code, and adapters" category = "main" optional = false @@ -41,7 +58,7 @@ tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (> [[package]] name = "certifi" -version = "2020.12.5" +version = "2021.5.30" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -86,7 +103,7 @@ pygments = ">=2.7.1" [[package]] name = "connect-openapi-client" -version = "22.0.7" +version = "22.0.8" description = "Connect Python OpenAPI Client" category = "main" optional = false @@ -207,13 +224,14 @@ python-versions = ">=3.6" [[package]] name = "httpcore" -version = "0.13.3" +version = "0.13.6" description = "A minimal low-level HTTP client." category = "main" optional = false python-versions = ">=3.6" [package.dependencies] +anyio = ">=3.0.0,<4.0.0" h11 = ">=0.11,<0.13" sniffio = ">=1.0.0,<2.0.0" @@ -222,7 +240,7 @@ http2 = ["h2 (>=3,<5)"] [[package]] name = "httpx" -version = "0.18.1" +version = "0.18.2" description = "The next generation HTTP client." category = "main" optional = false @@ -230,7 +248,7 @@ python-versions = ">=3.6" [package.dependencies] certifi = "*" -httpcore = ">=0.13.0,<0.14.0" +httpcore = ">=0.13.3,<0.14.0" rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} sniffio = "*" @@ -295,11 +313,11 @@ python-versions = "*" [[package]] name = "packaging" -version = "20.9" +version = "21.0" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [package.dependencies] pyparsing = ">=2.0.2" @@ -392,18 +410,19 @@ testing = ["coverage", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-cov" -version = "2.12.0" +version = "2.12.1" description = "Pytest plugin for measuring coverage." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} +coverage = ">=5.2.1" pytest = ">=4.6" +toml = "*" [package.extras] -testing = ["fields", "hunter", "process-tests (==2.0.2)", "six", "pytest-xdist", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-httpx" @@ -492,20 +511,20 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "urllib3" -version = "1.26.4" +version = "1.26.6" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] +brotli = ["brotlipy (>=0.6.0)"] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] -brotli = ["brotlipy (>=0.6.0)"] [[package]] name = "websockets" -version = "9.0.1" +version = "9.1" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" category = "main" optional = false @@ -514,16 +533,20 @@ python-versions = ">=3.6.1" [metadata] lock-version = "1.1" python-versions = "^3.8" -content-hash = "5f6efe0919a0929342e8ec9a15736150894ec8c12ffdf40443fb01af25d7530d" +content-hash = "c829dc46320012891729fffadd0b15eaf470ede7e300d24523535ccb8f679a16" [metadata.files] ansicolors = [ {file = "ansicolors-1.1.8-py2.py3-none-any.whl", hash = "sha256:00d2dde5a675579325902536738dd27e4fac1fd68f773fe36c21044eb559e187"}, {file = "ansicolors-1.1.8.zip", hash = "sha256:99f94f5e3348a0bcd43c82e5fc4414013ccc19d70bd939ad71e0133ce9c372e0"}, ] +anyio = [ + {file = "anyio-3.2.1-py3-none-any.whl", hash = "sha256:442678a3c7e1cdcdbc37dcfe4527aa851b1b0c9162653b516e9f509821691d50"}, + {file = "anyio-3.2.1.tar.gz", hash = "sha256:07968db9fa7c1ca5435a133dc62f988d84ef78e1d9b22814a59d1c62618afbc5"}, +] asgiref = [ - {file = "asgiref-3.3.4-py3-none-any.whl", hash = "sha256:92906c611ce6c967347bbfea733f13d6313901d54dcca88195eaeb52b2a8e8ee"}, - {file = "asgiref-3.3.4.tar.gz", hash = "sha256:d1216dfbdfb63826470995d31caed36225dcaf34f182e0fa257a4dd9e86f1b78"}, + {file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"}, + {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, @@ -534,8 +557,8 @@ attrs = [ {file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"}, ] certifi = [ - {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, - {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, + {file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"}, + {file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"}, ] chardet = [ {file = "chardet-4.0.0-py2.py3-none-any.whl", hash = "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"}, @@ -553,8 +576,8 @@ connect-markdown-renderer = [ {file = "connect_markdown_renderer-1.0.1-py3-none-any.whl", hash = "sha256:413a2995b28d490273a8f46dfebd90f70f62e301eff19253ae67859b2b710dc3"}, ] connect-openapi-client = [ - {file = "connect-openapi-client-22.0.7.tar.gz", hash = "sha256:f8a8e1d6485f84dbb5555297b4fdf4eec5ead6ee536a26e77a0e7c6eee539b93"}, - {file = "connect_openapi_client-22.0.7-py3-none-any.whl", hash = "sha256:1fb4cd2f7b1ceada8aafae2c031530e440b8750d208897ee33b41732632bde4b"}, + {file = "connect-openapi-client-22.0.8.tar.gz", hash = "sha256:9ce2da0a722274c8f846a3c077e330809a35e9f592c4ae327c02d899ad36c4eb"}, + {file = "connect_openapi_client-22.0.8-py3-none-any.whl", hash = "sha256:6419458a74775a7ac6ea8a1461c11718dc598e1b49fb8f1c6b1d4cacedd606f0"}, ] coverage = [ {file = "coverage-5.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:b6d534e4b2ab35c9f93f46229363e17f63c53ad01330df9f2d6bd1187e5eaacf"}, @@ -642,12 +665,12 @@ h11 = [ {file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"}, ] httpcore = [ - {file = "httpcore-0.13.3-py3-none-any.whl", hash = "sha256:ff614f0ef875b9e5fe0bdd459b31ea0eea282ff12dc82add83d68b3811ee94ad"}, - {file = "httpcore-0.13.3.tar.gz", hash = "sha256:5d674b57a11275904d4fd0819ca02f960c538e4472533620f322fc7db1ea0edc"}, + {file = "httpcore-0.13.6-py3-none-any.whl", hash = "sha256:db4c0dcb8323494d01b8c6d812d80091a31e520033e7b0120883d6f52da649ff"}, + {file = "httpcore-0.13.6.tar.gz", hash = "sha256:b0d16f0012ec88d8cc848f5a55f8a03158405f4bca02ee49bc4ca2c1fda49f3e"}, ] httpx = [ - {file = "httpx-0.18.1-py3-none-any.whl", hash = "sha256:ad2e3db847be736edc4b272c4d5788790a7e5789ef132fc6b5fef8aeb9e9f6e0"}, - {file = "httpx-0.18.1.tar.gz", hash = "sha256:0a2651dd2b9d7662c70d12ada5c290abcf57373b9633515fe4baa9f62566086f"}, + {file = "httpx-0.18.2-py3-none-any.whl", hash = "sha256:979afafecb7d22a1d10340bafb403cf2cb75aff214426ff206521fc79d26408c"}, + {file = "httpx-0.18.2.tar.gz", hash = "sha256:9f99c15d33642d38bce8405df088c1c4cfd940284b4290cacbfb02e64f4877c6"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, @@ -673,8 +696,8 @@ mistune = [ {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, ] packaging = [ - {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, - {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, + {file = "packaging-21.0-py3-none-any.whl", hash = "sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14"}, + {file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"}, ] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, @@ -709,8 +732,8 @@ pytest-asyncio = [ {file = "pytest_asyncio-0.15.1-py3-none-any.whl", hash = "sha256:3042bcdf1c5d978f6b74d96a151c4cfb9dcece65006198389ccd7e6c60eb1eea"}, ] pytest-cov = [ - {file = "pytest-cov-2.12.0.tar.gz", hash = "sha256:8535764137fecce504a49c2b742288e3d34bc09eed298ad65963616cc98fd45e"}, - {file = "pytest_cov-2.12.0-py2.py3-none-any.whl", hash = "sha256:95d4933dcbbacfa377bb60b29801daa30d90c33981ab2a79e9ab4452c165066e"}, + {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"}, + {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, ] pytest-httpx = [ {file = "pytest_httpx-0.12.0-py3-none-any.whl", hash = "sha256:e262932f2d3ce380da8273c7bacbcfdc2c94e167fa94da29571caaf1f4d3ba27"}, @@ -768,41 +791,41 @@ toml = [ {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] urllib3 = [ - {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"}, - {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"}, + {file = "urllib3-1.26.6-py2.py3-none-any.whl", hash = "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4"}, + {file = "urllib3-1.26.6.tar.gz", hash = "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"}, ] websockets = [ - {file = "websockets-9.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:69a5972956759224c5201007ff49398a78a23baca344185533093602f56cbbbe"}, - {file = "websockets-9.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:33c59a9151bd0b133e6314063f5a5924273e6ff038e7ac9ec7dcea40d0619723"}, - {file = "websockets-9.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:77866cba716a78a056612541f9cc47de93ba70cee3395337131cd3cb87a10273"}, - {file = "websockets-9.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:7cfbe5339dc5a2dc813e96626fa9e659e252df78fbef5b8e67ad17578a78c147"}, - {file = "websockets-9.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:966fe1574708927322d0b5caff0b49fd7ab5f889eb4ba6aefa5718be3e7c879f"}, - {file = "websockets-9.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:ccce35e8ab229a5b518bc72391ea5989fb6fec9817e772897d67ff1a12cc1a8b"}, - {file = "websockets-9.0.1-cp36-cp36m-win32.whl", hash = "sha256:a96ed836dae26d50ef69648ac804c7e53aca81dd9c90ef1128acef3925b7e055"}, - {file = "websockets-9.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:16c1875f957c685e8bd815cd164eaf46373940c14b01b0baff81169249c95922"}, - {file = "websockets-9.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9b0ac168c258c6e42cabfef699c1282043e9fa0e7d6a211f93998dc8b2249238"}, - {file = "websockets-9.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:66c112ef31a8b419dac4a1a5baaa2e76610ed184801123e80a0ba9c7173177ff"}, - {file = "websockets-9.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:9480bb6f41f76de3fd7a8937834f740fd331a3af2d92dd15d45a2c27c6b546e6"}, - {file = "websockets-9.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:8d084ac3da927dd252fe11cb082a75dbb377fbb11e8ebdc095297ef44d0764aa"}, - {file = "websockets-9.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3f768eeaa001efc23d140701e666b18f76b9aaaefc38889bdb3a47afabdbd199"}, - {file = "websockets-9.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:a864ecd9e3a862342b6288129cd0557e2d0a785ec82ded4b562254e326e5a566"}, - {file = "websockets-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:55299ba19717d6cfc5341d1653d2ada41986073978bf1f6128cdf0fd4bc240c1"}, - {file = "websockets-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:1cf7b0b78ed8134c6043d6425d53ee1232de1d07e4df02d446e4d0bff93270c1"}, - {file = "websockets-9.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e496386bfb8e1e89824bb488f387bca8eff304c67fd030f1bd40d0c41a8f8734"}, - {file = "websockets-9.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:f876ae0e6acfcce6cd03601f9bda37f210b568888cba99075f64503bf2174a08"}, - {file = "websockets-9.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:163c6cfdf74e2034b22c51c727b7f7b4aae2fa949555aeafd79dcffab34b2bd3"}, - {file = "websockets-9.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:40a73c4f9d0a5796688753c115b3b5a29269e0bcb8661f5d0f9e1352b81839fd"}, - {file = "websockets-9.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:0b5c20681b1e12df80499e3323e3cdb2b813553e2553aa392d3db8a063100fb8"}, - {file = "websockets-9.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3b61adeb0bc4b34a62ec231b320967d7ca61b40ee26f8ec8d93d1d5ae292deef"}, - {file = "websockets-9.0.1-cp38-cp38-win32.whl", hash = "sha256:3437fd1fce7a40fa315080ab61c7744695a2ca3e8d5d6e7576d09c4b697b7f38"}, - {file = "websockets-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:0943a856b38ecafc5ab96261687d1e744d4307815927911eb76ae609b5d21e0e"}, - {file = "websockets-9.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b15043e495ff7a601a98d4d5f019f1ae4b6b643d9dbcf3d9398af58fe5545148"}, - {file = "websockets-9.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:60ecbc6ce686dc1d640d9771342e3f4477f21fa65a10235b390c45c28b3c2399"}, - {file = "websockets-9.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:407a215d4d92576b582dac3bb8a66e0d7d1428abb1c48b2c0cf7e8e71c87e2f1"}, - {file = "websockets-9.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:5a1f7580a035e97d015963c6935d5ba9aabca8fca056aaef73e82d3bcfee6d79"}, - {file = "websockets-9.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:3a69e07ed385b383adc0731effe47680caa60232cb32bf43e38dd1e48c602126"}, - {file = "websockets-9.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a508a1e2630ebd88c4a60e0443a4bc3b6370d2a9c2c2d534ab0d718cd63ad589"}, - {file = "websockets-9.0.1-cp39-cp39-win32.whl", hash = "sha256:8c0a414ffebb1cd5fc603cc1cb5347f5e564762aa8f12c411507c7345907781f"}, - {file = "websockets-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:73a9195c6e009d0c34d0519eb75c5d78e5bd0d2e3998f35b0c35e1e23b3f5a6b"}, - {file = "websockets-9.0.1.tar.gz", hash = "sha256:2ab64e9fd18e57a66b63a8774e337d81d6366412bef65c7d71f87ad5c4faeed5"}, + {file = "websockets-9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da"}, + {file = "websockets-9.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4"}, + {file = "websockets-9.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2cf04601633a4ec176b9cc3d3e73789c037641001dbfaf7c411f89cd3e04fcaf"}, + {file = "websockets-9.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:5c8f0d82ea2468282e08b0cf5307f3ad022290ed50c45d5cb7767957ca782880"}, + {file = "websockets-9.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:caa68c95bc1776d3521f81eeb4d5b9438be92514ec2a79fececda814099c8314"}, + {file = "websockets-9.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:d2c2d9b24d3c65b5a02cac12cbb4e4194e590314519ed49db2f67ef561c3cf58"}, + {file = "websockets-9.1-cp36-cp36m-win32.whl", hash = "sha256:f31722f1c033c198aa4a39a01905951c00bd1c74f922e8afc1b1c62adbcdd56a"}, + {file = "websockets-9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:3ddff38894c7857c476feb3538dd847514379d6dc844961dc99f04b0384b1b1b"}, + {file = "websockets-9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:51d04df04ed9d08077d10ccbe21e6805791b78eac49d16d30a1f1fe2e44ba0af"}, + {file = "websockets-9.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f68c352a68e5fdf1e97288d5cec9296664c590c25932a8476224124aaf90dbcd"}, + {file = "websockets-9.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:b43b13e5622c5a53ab12f3272e6f42f1ce37cd5b6684b2676cb365403295cd40"}, + {file = "websockets-9.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:9147868bb0cc01e6846606cd65cbf9c58598f187b96d14dd1ca17338b08793bb"}, + {file = "websockets-9.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:836d14eb53b500fd92bd5db2fc5894f7c72b634f9c2a28f546f75967503d8e25"}, + {file = "websockets-9.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:48c222feb3ced18f3dc61168ca18952a22fb88e5eb8902d2bf1b50faefdc34a2"}, + {file = "websockets-9.1-cp37-cp37m-win32.whl", hash = "sha256:900589e19200be76dd7cbaa95e9771605b5ce3f62512d039fb3bc5da9014912a"}, + {file = "websockets-9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ab5ee15d3462198c794c49ccd31773d8a2b8c17d622aa184f669d2b98c2f0857"}, + {file = "websockets-9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:85e701a6c316b7067f1e8675c638036a796fe5116783a4c932e7eb8e305a3ffe"}, + {file = "websockets-9.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b2e71c4670ebe1067fa8632f0d081e47254ee2d3d409de54168b43b0ba9147e0"}, + {file = "websockets-9.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:230a3506df6b5f446fed2398e58dcaafdff12d67fe1397dff196411a9e820d02"}, + {file = "websockets-9.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:7df3596838b2a0c07c6f6d67752c53859a54993d4f062689fdf547cb56d0f84f"}, + {file = "websockets-9.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:826ccf85d4514609219725ba4a7abd569228c2c9f1968e8be05be366f68291ec"}, + {file = "websockets-9.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:0dd4eb8e0bbf365d6f652711ce21b8fd2b596f873d32aabb0fbb53ec604418cc"}, + {file = "websockets-9.1-cp38-cp38-win32.whl", hash = "sha256:1d0971cc7251aeff955aa742ec541ee8aaea4bb2ebf0245748fbec62f744a37e"}, + {file = "websockets-9.1-cp38-cp38-win_amd64.whl", hash = "sha256:7189e51955f9268b2bdd6cc537e0faa06f8fffda7fb386e5922c6391de51b077"}, + {file = "websockets-9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e9e5fd6dbdf95d99bc03732ded1fc8ef22ebbc05999ac7e0c7bf57fe6e4e5ae2"}, + {file = "websockets-9.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9e7fdc775fe7403dbd8bc883ba59576a6232eac96dacb56512daacf7af5d618d"}, + {file = "websockets-9.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:597c28f3aa7a09e8c070a86b03107094ee5cdafcc0d55f2f2eac92faac8dc67d"}, + {file = "websockets-9.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:ad893d889bc700a5835e0a95a3e4f2c39e91577ab232a3dc03c262a0f8fc4b5c"}, + {file = "websockets-9.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:1d6b4fddb12ab9adf87b843cd4316c4bd602db8d5efd2fb83147f0458fe85135"}, + {file = "websockets-9.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:ebf459a1c069f9866d8569439c06193c586e72c9330db1390af7c6a0a32c4afd"}, + {file = "websockets-9.1-cp39-cp39-win32.whl", hash = "sha256:be5fd35e99970518547edc906efab29afd392319f020c3c58b0e1a158e16ed20"}, + {file = "websockets-9.1-cp39-cp39-win_amd64.whl", hash = "sha256:85db8090ba94e22d964498a47fdd933b8875a1add6ebc514c7ac8703eb97bbf0"}, + {file = "websockets-9.1.tar.gz", hash = "sha256:276d2339ebf0df4f45df453923ebd2270b87900eda5dfd4a6b0cfa15f82111c3"}, ] diff --git a/pyproject.toml b/pyproject.toml index 2b00bcd..5ebcadb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ cextrun = 'connect.eaas.main:main' [tool.poetry.dependencies] python = "^3.8" websockets = "^9.0.1" -connect-openapi-client = "^22.0.7" +connect-openapi-client = "^22.0.8" logzio-python-handler = "^3.0.0" [tool.poetry.dev-dependencies] diff --git a/tests/test_logging.py b/tests/test_logging.py index 6230a8f..413b552 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -1,6 +1,9 @@ import logging -from connect.eaas.logging import ExtensionLogHandler +from urllib3.response import HTTPResponse +from requests.models import Response + +from connect.eaas.logging import ExtensionLogHandler, RequestLogger def test_extension_log_handler(): @@ -17,3 +20,154 @@ def test_extension_log_handler(): None, )) assert extra_fields['field'] == 'value' + + +def test_request_logger_request(caplog): + rl = RequestLogger(logging.getLogger('eaas.extension')) + + with caplog.at_level(logging.DEBUG): + rl.log_request('POST', 'https://example.com', {}) + + assert '\n'.join( + [ + '--- HTTP Request ---', + "POST https://example.com ", + '', + ], + ) == caplog.records[0].message + + +def test_request_logger_request_params(caplog): + rl = RequestLogger(logging.getLogger('eaas.extension')) + + with caplog.at_level(logging.DEBUG): + rl.log_request('POST', 'https://example.com', {'params': {'a': 'va'}}) + + assert '\n'.join( + [ + '--- HTTP Request ---', + "POST https://example.com?a=va ", + '', + ], + ) == caplog.records[0].message + + +def test_request_logger_request_with_qs(caplog): + rl = RequestLogger(logging.getLogger('eaas.extension')) + + with caplog.at_level(logging.DEBUG): + rl.log_request('GET', 'https://example.com?queryparam=value', {}) + + assert '\n'.join( + [ + '--- HTTP Request ---', + "GET https://example.com?queryparam=value ", + '', + ], + ) == caplog.records[0].message + + +def test_request_logger_request_with_headers(caplog): + rl = RequestLogger(logging.getLogger('eaas.extension')) + + headers = { + 'Authorization': 'ApiKey SU-000:xxxx', + } + + with caplog.at_level(logging.DEBUG): + rl.log_request('GET', 'https://example.com', {'headers': headers}) + + assert '\n'.join( + [ + '--- HTTP Request ---', + "GET https://example.com ", + 'Authorization: ApiKey SU-000:xxxx', + '', + ], + ) == caplog.records[0].message + + +def test_request_logger_request_with_json_body(caplog): + rl = RequestLogger(logging.getLogger('eaas.extension')) + + json = { + 'test': 'data', + } + + with caplog.at_level(logging.DEBUG): + rl.log_request('GET', 'https://example.com', {'json': json}) + + assert '\n'.join( + [ + '--- HTTP Request ---', + "GET https://example.com ", + '{', + ' "test": "data"', + '}', + '', + ], + ) == caplog.records[0].message + + +def test_request_logger_response(caplog): + rl = RequestLogger(logging.getLogger('eaas.extension')) + + rsp = Response() + rsp.raw = HTTPResponse() + + rsp.status_code = 200 + rsp.raw.reason = 'OK' + + with caplog.at_level(logging.DEBUG): + rl.log_response(rsp) + + assert '\n'.join( + [ + '--- HTTP Response ---', + '200 OK', + '', + ], + ) == caplog.records[0].message + + rsp = Response() + rsp.status_code = 200 + rsp.reason_phrase = 'OK' + + with caplog.at_level(logging.DEBUG): + rl.log_response(rsp) + + assert '\n'.join( + [ + '--- HTTP Response ---', + '200 OK', + '', + ], + ) == caplog.records[0].message + + +def test_request_logger_response_json(mocker, caplog): + json = {'id': 'XX-1234', 'name': 'XXX'} + mocker.patch('requests.models.Response.json', return_value=json) + + rl = RequestLogger(logging.getLogger('eaas.extension')) + + rsp = Response() + rsp.raw = HTTPResponse() + rsp.headers = {'Content-Type': 'application/json'} + rsp.status_code = 200 + rsp.raw.reason = 'OK' + + with caplog.at_level(logging.DEBUG): + rl.log_response(rsp) + assert '\n'.join( + [ + '--- HTTP Response ---', + '200 OK', + 'Content-Type: application/json', + '{', + ' "id": "XX-1234",', + ' "name": "XXX"', + '}', + '', + ], + ) == caplog.records[0].message diff --git a/tests/test_worker.py b/tests/test_worker.py index 7501232..cdc6621 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -63,7 +63,7 @@ def get_descriptor(cls): ).to_json() handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', data_to_send, ['receive', 'send'], ) @@ -144,7 +144,7 @@ def process_asset_purchase_request(self, request): ] handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', data_to_send, ['receive', 'send', 'send', 'receive'], ) @@ -234,7 +234,7 @@ def process_tier_config_setup_request(self, request): ] handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', data_to_send, ['receive', 'send', 'send', 'receive'], ) @@ -307,7 +307,7 @@ def get_descriptor(cls): ] handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', data_to_send, ['receive', 'send', 'send'], ) @@ -362,7 +362,7 @@ def get_descriptor(cls): ] handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', data_to_send, ['receive', 'send', 'send', 'send'], ) @@ -416,7 +416,7 @@ def get_descriptor(cls): ] handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', data_to_send, ['receive', 'send', 'send'], ) @@ -444,7 +444,7 @@ async def test_connection_closed_error(mocker, ws_server, unused_port, caplog): }, ) handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', None, [], ) @@ -461,7 +461,7 @@ async def test_connection_closed_error(mocker, ws_server, unused_port, caplog): assert ( f'Disconnected from: ws://127.0.0.1:{unused_port}' - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002, retry in 2s' + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0, retry in 2s' ) in caplog.text @@ -480,7 +480,7 @@ async def test_connection_websocket_exception(mocker, ws_server, unused_port, ca }, ) handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', None, [], ) @@ -529,7 +529,7 @@ def get_descriptor(cls): mocker.patch('connect.eaas.worker.get_extension_type', return_value='sync') handler = WSHandler( - '/public/v1/devops/ws/ENV-000-0001/INS-000-0002', + '/public/v1/devops/ws/ENV-000-0001/INS-000-0002?running_tasks=0', None, ['receive', 'send'], ) diff --git a/tests/utils.py b/tests/utils.py index 897ef57..a0689c4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -4,9 +4,13 @@ # Copyright (c) 2021 Ingram Micro. All Rights Reserved. # import asyncio +import logging import json +logger = logging.getLogger('connect.eaas') + + class WSHandler: def __init__(self, path, data, actions): self.path = path @@ -37,6 +41,7 @@ async def receive_data(self, ws): data = await ws.recv() if data: self.received.append(json.loads(data)) + logger.info(f'received: {self.received}') def assert_received(self, data): assert data in self.received