Skip to content

Commit 1807434

Browse files
dvarrazzoWSH032
andauthored
fix: don't use module-level logging methods (#46)
* fix: don't use module-level logging methods Calling these methods might add handlers to the root logger, which can interfere with applications that don't use it. Fix #45. * refactor: make `logger` private * docs(CHANGELOG): update `CHANGELOG.md` * test(codecov): add `pragma: no cover` for unreachable code --------- Co-authored-by: Sean Wang <126865849+WSH032@users.noreply.github.com> Co-authored-by: WSH032 <614337162@qq.com>
1 parent ebab5ca commit 1807434

File tree

5 files changed

+48
-19
lines changed

5 files changed

+48
-19
lines changed

CHANGELOG.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3131

3232
- [#30](https://github.com/WSH032/fastapi-proxy-lib/pull/30) - fix(internal): use `websocket` in favor of `websocket_route`. Thanks [@WSH032](https://github.com/WSH032)!
3333

34-
### Removed
35-
36-
- [#49](https://github.com/WSH032/fastapi-proxy-lib/pull/49) - Drop support for `Python 3.8`.
37-
3834
### Fixed
3935

36+
- [#46](https://github.com/WSH032/fastapi-proxy-lib/pull/46) - fix: don't use module-level logging methods. Thanks [@dvarrazzo](https://github.com/dvarrazzo)
4037
- [#49](https://github.com/WSH032/fastapi-proxy-lib/pull/49) - fix!: bump `httpx-ws >= 0.7.1` to fix frankie567/httpx-ws#29. Thanks [@WSH032](https://github.com/WSH032)!
4138

39+
### Removed
40+
41+
- [#49](https://github.com/WSH032/fastapi-proxy-lib/pull/49) - Drop support for `Python 3.8`.
42+
4243
### Internal
4344

4445
- [#47](https://github.com/WSH032/fastapi-proxy-lib/pull/47) - test: do not use deprecated and removed APIs of httpx. Thanks [@WSH032](https://github.com/WSH032)!

src/fastapi_proxy_lib/core/_tool.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
"_RejectedProxyRequestError",
4444
)
4545

46+
_logger = logging.getLogger(__name__)
47+
4648
#################### Constant ####################
4749

4850

@@ -361,7 +363,7 @@ def check_http_version(
361363
return return_err_msg_response(
362364
error,
363365
status_code=status.HTTP_505_HTTP_VERSION_NOT_SUPPORTED,
364-
logger=logging.info,
366+
logger=_logger.info,
365367
)
366368

367369

src/fastapi_proxy_lib/core/http.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
"ForwardHttpProxy",
4242
)
4343

44+
_logger = logging.getLogger(__name__)
45+
4446
#################### Data Model ####################
4547

4648

@@ -272,7 +274,7 @@ async def send_request_to_target( # pyright: ignore [reportIncompatibleMethodOv
272274
)
273275

274276
# DEBUG: 用于调试的记录
275-
logging.debug(
277+
_logger.debug(
276278
"HTTP: client:%s ; url:%s ; head:%s",
277279
request.client,
278280
proxy_request.url,
@@ -434,7 +436,7 @@ async def proxy( # pyright: ignore [reportIncompatibleMethodOverride]
434436
"Oops! Something wrong! Please contact the server maintainer!"
435437
),
436438
status_code=starlette_status.HTTP_502_BAD_GATEWAY,
437-
logger=logging.exception,
439+
logger=_logger.exception,
438440
_msg=msg,
439441
_exc_info=e,
440442
)
@@ -550,7 +552,7 @@ async def proxy( # pyright: ignore [reportIncompatibleMethodOverride]
550552
return return_err_msg_response(
551553
e,
552554
status_code=starlette_status.HTTP_400_BAD_REQUEST,
553-
logger=logging.critical,
555+
logger=_logger.critical,
554556
)
555557

556558
# 进行请求过滤
@@ -575,7 +577,7 @@ async def proxy( # pyright: ignore [reportIncompatibleMethodOverride]
575577
return return_err_msg_response(
576578
e,
577579
status_code=starlette_status.HTTP_500_INTERNAL_SERVER_ERROR,
578-
logger=logging.exception,
580+
logger=_logger.exception,
579581
_exc_info=e,
580582
)
581583
# 请注意,我们不返回其他错误给客户端,因为这可能涉及到服务器内部的信息泄露

src/fastapi_proxy_lib/core/websocket.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
# 这些是私有模块,无法确定以后版本是否会改变,为了保证运行时不会出错,我们使用TYPE_CHECKING
4848
from httpx._types import HeaderTypes, QueryParamTypes
4949

50+
_logger = logging.getLogger(__name__)
5051

5152
#################### Data Model ####################
5253

@@ -196,7 +197,7 @@ async def _httpx_ws_receive_bytes_or_str(
196197
return bytes(event.data)
197198
else: # pragma: no cover # 无法测试这个分支,因为无法发送这种消息,正常来说也不会被执行,所以我们这里记录critical
198199
msg = f"Invalid message type received: {type(event)}"
199-
logging.critical(msg)
200+
_logger.critical(msg)
200201
raise httpx_ws.WebSocketInvalidTypeReceived(event)
201202

202203

@@ -365,12 +366,12 @@ async def _close_ws(
365366
client_error: {client_error}
366367
server_error: {server_error}\
367368
"""
368-
logging.warning(msg)
369+
_logger.warning(msg)
369370

370371
except (
371372
Exception
372373
) as e: # pragma: no cover # 这个分支是一个保险分支,通常无法执行,所以只进行记录
373-
logging.error(
374+
_logger.error(
374375
f"{e} when close ws connection. client: {client_to_server_task}, server:{server_to_client_task}"
375376
)
376377
raise
@@ -389,7 +390,7 @@ async def _close_ws(
389390
except Exception as e: # pragma: no cover
390391
# 这个分支是一个保险分支,通常无法执行,所以只进行记录
391392
# 不会触发的原因是,负责服务端 ws 连接的 httpx_ws 支持重复调用close而不引发错误
392-
logging.debug("Unexpected error for debug", exc_info=e)
393+
_logger.debug("Unexpected error for debug", exc_info=e)
393394

394395

395396
#################### # ####################
@@ -502,7 +503,7 @@ async def send_request_to_target( # pyright: ignore [reportIncompatibleMethodOv
502503
return check_result
503504

504505
# DEBUG: 用于调试的记录
505-
logging.debug(
506+
_logger.debug(
506507
"WS: client:%s ; url:%s ; params:%s ; headers:%s",
507508
websocket.client,
508509
target_url,
@@ -620,14 +621,14 @@ async def send_request_to_target( # pyright: ignore [reportIncompatibleMethodOv
620621
try:
621622
await asyncio.wait_for(pending_task, timeout=1)
622623
except asyncio.TimeoutError:
623-
logging.debug(f"{pending} TimeoutError, it's normal.")
624-
except Exception as e:
624+
_logger.debug(f"{pending} TimeoutError, it's normal.")
625+
except Exception as e: # pragma: no cover # usually unreachable
625626
# 取消期间可能另一个ws会发生异常,这个是正常情况,且会被 asyncio.wait_for 传播
626-
logging.debug(
627+
_logger.debug(
627628
f"{pending} raise error when being canceled, it's normal. error: {e}"
628629
)
629-
except Exception as e: # pragma: no cover # 这个是保险分支,通常无法执行
630-
logging.warning(
630+
except Exception as e: # pragma: no cover # usually unreachable
631+
_logger.warning(
631632
f"Something wrong, please contact the developer. error: {e}"
632633
)
633634
raise

tests/test_http.py

+23
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# noqa: D100
22

33

4+
import logging
5+
46
import httpx
57
import pytest
68
from fastapi_proxy_lib.core.tool import default_proxy_filter
@@ -244,6 +246,27 @@ async def test_cookie_leakage(
244246
assert "foo" not in r.json() # not leaked
245247
assert r.json()["a"] == "b" # send cookies normally
246248

249+
@pytest.mark.anyio()
250+
async def test_no_logging_basic_config_call(
251+
self, tool_4_test_fixture: Tool4TestFixture, monkeypatch: pytest.MonkeyPatch
252+
) -> None:
253+
"""Test that we don't accidentally call `logging.basicConfig()`.
254+
255+
See issue #45
256+
"""
257+
root = logging.getLogger()
258+
monkeypatch.setattr(root, "handlers", [])
259+
260+
client_for_conn_to_proxy_server = (
261+
tool_4_test_fixture.client_for_conn_to_proxy_server
262+
)
263+
proxy_server_base_url = tool_4_test_fixture.proxy_server_base_url
264+
265+
resp = await client_for_conn_to_proxy_server.get(proxy_server_base_url)
266+
assert resp.is_success
267+
268+
assert not root.handlers, "logging handler added"
269+
247270

248271
class TestForwardHttpProxy(AbstractTestProxy):
249272
"""For testing forward http proxy."""

0 commit comments

Comments
 (0)