beans-logging-fastapi 1.1.1__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- beans_logging_fastapi/__init__.py +1 -1
- beans_logging_fastapi/__version__.py +1 -3
- beans_logging_fastapi/_async_log.py +38 -26
- beans_logging_fastapi/_base.py +25 -18
- beans_logging_fastapi/_filters.py +9 -4
- beans_logging_fastapi/_formats.py +53 -35
- beans_logging_fastapi/_handlers.py +56 -42
- beans_logging_fastapi/_middlewares.py +40 -30
- beans_logging_fastapi-2.0.0.dist-info/METADATA +497 -0
- beans_logging_fastapi-2.0.0.dist-info/RECORD +13 -0
- {beans_logging_fastapi-1.1.1.dist-info → beans_logging_fastapi-2.0.0.dist-info}/WHEEL +1 -1
- beans_logging_fastapi-1.1.1.dist-info/LICENCE.txt → beans_logging_fastapi-2.0.0.dist-info/licenses/LICENSE.txt +1 -1
- {beans_logging_fastapi-1.1.1.dist-info → beans_logging_fastapi-2.0.0.dist-info}/top_level.txt +0 -1
- beans_logging_fastapi-1.1.1.dist-info/METADATA +0 -385
- beans_logging_fastapi-1.1.1.dist-info/RECORD +0 -16
- tests/__init__.py +0 -1
- tests/conftest.py +0 -16
- tests/test_beans_logging_fastapi.py +0 -24
|
@@ -1,42 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
from typing import Any
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
from pydantic import validate_arguments
|
|
3
|
+
from pydantic import validate_call
|
|
6
4
|
from fastapi import Request
|
|
7
5
|
from fastapi.concurrency import run_in_threadpool
|
|
8
6
|
|
|
9
7
|
from beans_logging import logger, Logger
|
|
10
8
|
|
|
11
9
|
|
|
12
|
-
@
|
|
10
|
+
@validate_call(config={"arbitrary_types_allowed": True})
|
|
13
11
|
async def async_log_http_error(
|
|
14
12
|
request: Request,
|
|
15
13
|
status_code: int,
|
|
16
|
-
msg_format: str =
|
|
17
|
-
|
|
14
|
+
msg_format: str = (
|
|
15
|
+
'<n><w>[{request_id}]</w></n> {client_host} {user_id} "<u>{method} {url_path}</u> '
|
|
16
|
+
'HTTP/{http_version}" <n>{status_code}</n>'
|
|
17
|
+
),
|
|
18
|
+
) -> None:
|
|
18
19
|
"""Log HTTP error for unhandled Exception.
|
|
19
20
|
|
|
20
21
|
Args:
|
|
21
22
|
request (Request, required): Request instance.
|
|
22
23
|
status_code (int , required): HTTP status code.
|
|
23
|
-
msg_format (str , optional): Message format. Defaults to
|
|
24
|
+
msg_format (str , optional): Message format. Defaults to
|
|
25
|
+
'<n><w>[{request_id}]</w></n> {client_host} {user_id} "<u>{method} {url_path}</u> HTTP/{http_version}"
|
|
26
|
+
<n>{status_code}</n>'.
|
|
24
27
|
"""
|
|
25
28
|
|
|
26
|
-
_http_info:
|
|
29
|
+
_http_info: dict[str, Any] = {"request_id": request.state.request_id}
|
|
27
30
|
if hasattr(request.state, "http_info") and isinstance(
|
|
28
31
|
request.state.http_info, dict
|
|
29
32
|
):
|
|
30
|
-
_http_info:
|
|
33
|
+
_http_info: dict[str, Any] = request.state.http_info
|
|
31
34
|
_http_info["status_code"] = status_code
|
|
32
35
|
|
|
33
36
|
_msg = msg_format.format(**_http_info)
|
|
34
37
|
_logger: Logger = logger.opt(colors=True, record=True).bind(http_info=_http_info)
|
|
35
38
|
await run_in_threadpool(_logger.error, _msg)
|
|
39
|
+
return
|
|
36
40
|
|
|
37
41
|
|
|
38
|
-
@
|
|
39
|
-
async def async_log_trace(message: str):
|
|
42
|
+
@validate_call
|
|
43
|
+
async def async_log_trace(message: str) -> None:
|
|
40
44
|
"""Log trace message.
|
|
41
45
|
|
|
42
46
|
Args:
|
|
@@ -44,10 +48,11 @@ async def async_log_trace(message: str):
|
|
|
44
48
|
"""
|
|
45
49
|
|
|
46
50
|
await run_in_threadpool(logger.trace, message)
|
|
51
|
+
return
|
|
47
52
|
|
|
48
53
|
|
|
49
|
-
@
|
|
50
|
-
async def async_log_debug(message: str):
|
|
54
|
+
@validate_call
|
|
55
|
+
async def async_log_debug(message: str) -> None:
|
|
51
56
|
"""Log debug message.
|
|
52
57
|
|
|
53
58
|
Args:
|
|
@@ -55,10 +60,11 @@ async def async_log_debug(message: str):
|
|
|
55
60
|
"""
|
|
56
61
|
|
|
57
62
|
await run_in_threadpool(logger.debug, message)
|
|
63
|
+
return
|
|
58
64
|
|
|
59
65
|
|
|
60
|
-
@
|
|
61
|
-
async def async_log_info(message: str):
|
|
66
|
+
@validate_call
|
|
67
|
+
async def async_log_info(message: str) -> None:
|
|
62
68
|
"""Log info message.
|
|
63
69
|
|
|
64
70
|
Args:
|
|
@@ -66,10 +72,11 @@ async def async_log_info(message: str):
|
|
|
66
72
|
"""
|
|
67
73
|
|
|
68
74
|
await run_in_threadpool(logger.info, message)
|
|
75
|
+
return
|
|
69
76
|
|
|
70
77
|
|
|
71
|
-
@
|
|
72
|
-
async def async_log_success(message: str):
|
|
78
|
+
@validate_call
|
|
79
|
+
async def async_log_success(message: str) -> None:
|
|
73
80
|
"""Log success message.
|
|
74
81
|
|
|
75
82
|
Args:
|
|
@@ -77,10 +84,11 @@ async def async_log_success(message: str):
|
|
|
77
84
|
"""
|
|
78
85
|
|
|
79
86
|
await run_in_threadpool(logger.success, message)
|
|
87
|
+
return
|
|
80
88
|
|
|
81
89
|
|
|
82
|
-
@
|
|
83
|
-
async def async_log_warning(message: str):
|
|
90
|
+
@validate_call
|
|
91
|
+
async def async_log_warning(message: str) -> None:
|
|
84
92
|
"""Log warning message.
|
|
85
93
|
|
|
86
94
|
Args:
|
|
@@ -88,10 +96,11 @@ async def async_log_warning(message: str):
|
|
|
88
96
|
"""
|
|
89
97
|
|
|
90
98
|
await run_in_threadpool(logger.warning, message)
|
|
99
|
+
return
|
|
91
100
|
|
|
92
101
|
|
|
93
|
-
@
|
|
94
|
-
async def async_log_error(message: str):
|
|
102
|
+
@validate_call
|
|
103
|
+
async def async_log_error(message: str) -> None:
|
|
95
104
|
"""Log error message.
|
|
96
105
|
|
|
97
106
|
Args:
|
|
@@ -99,10 +108,11 @@ async def async_log_error(message: str):
|
|
|
99
108
|
"""
|
|
100
109
|
|
|
101
110
|
await run_in_threadpool(logger.error, message)
|
|
111
|
+
return
|
|
102
112
|
|
|
103
113
|
|
|
104
|
-
@
|
|
105
|
-
async def async_log_critical(message: str):
|
|
114
|
+
@validate_call
|
|
115
|
+
async def async_log_critical(message: str) -> None:
|
|
106
116
|
"""Log critical message.
|
|
107
117
|
|
|
108
118
|
Args:
|
|
@@ -110,10 +120,11 @@ async def async_log_critical(message: str):
|
|
|
110
120
|
"""
|
|
111
121
|
|
|
112
122
|
await run_in_threadpool(logger.critical, message)
|
|
123
|
+
return
|
|
113
124
|
|
|
114
125
|
|
|
115
|
-
@
|
|
116
|
-
async def async_log_level(level: str, message: str):
|
|
126
|
+
@validate_call
|
|
127
|
+
async def async_log_level(level: str, message: str) -> None:
|
|
117
128
|
"""Log level message.
|
|
118
129
|
|
|
119
130
|
Args:
|
|
@@ -122,6 +133,7 @@ async def async_log_level(level: str, message: str):
|
|
|
122
133
|
"""
|
|
123
134
|
|
|
124
135
|
await run_in_threadpool(logger.log, level, message)
|
|
136
|
+
return
|
|
125
137
|
|
|
126
138
|
|
|
127
139
|
__all__ = [
|
beans_logging_fastapi/_base.py
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from typing import Dict, Any
|
|
1
|
+
from typing import Any
|
|
4
2
|
|
|
5
3
|
from fastapi import Request, Response
|
|
6
4
|
from fastapi.concurrency import run_in_threadpool
|
|
@@ -16,16 +14,23 @@ class HttpAccessLogMiddleware(BaseHTTPMiddleware):
|
|
|
16
14
|
BaseHTTPMiddleware: Base HTTP middleware class from starlette.
|
|
17
15
|
|
|
18
16
|
Attributes:
|
|
19
|
-
_DEBUG_FORMAT (str ): Default http access log debug message format. Defaults to
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
_DEBUG_FORMAT (str ): Default http access log debug message format. Defaults to
|
|
18
|
+
'<n>[{request_id}]</n> {client_host} {user_id} "<u>{method} {url_path}</u> HTTP/{http_version}"'.
|
|
19
|
+
_MSG_FORMAT (str ): Default http access log message format. Defaults to
|
|
20
|
+
'<n><w>[{request_id}]</w></n> {client_host} {user_id} "<u>{method} {url_path}</u> HTTP/{http_version}"
|
|
21
|
+
{status_code} {content_length}B {response_time}ms'.
|
|
22
|
+
|
|
23
|
+
debug_format (str ): Http access log debug message format. Defaults to
|
|
24
|
+
`HttpAccessLogMiddleware._DEBUG_FORMAT`.
|
|
23
25
|
msg_format (str ): Http access log message format. Defaults to `HttpAccessLogMiddleware._MSG_FORMAT`.
|
|
24
26
|
use_debug_log (bool): If True, use debug log to log http access log. Defaults to True.
|
|
25
27
|
"""
|
|
26
28
|
|
|
27
29
|
_DEBUG_FORMAT = '<n>[{request_id}]</n> {client_host} {user_id} "<u>{method} {url_path}</u> HTTP/{http_version}"'
|
|
28
|
-
_MSG_FORMAT =
|
|
30
|
+
_MSG_FORMAT = (
|
|
31
|
+
'<n><w>[{request_id}]</w></n> {client_host} {user_id} "<u>{method} {url_path}</u> '
|
|
32
|
+
'HTTP/{http_version}" {status_code} {content_length}B {response_time}ms'
|
|
33
|
+
)
|
|
29
34
|
|
|
30
35
|
def __init__(
|
|
31
36
|
self,
|
|
@@ -42,13 +47,13 @@ class HttpAccessLogMiddleware(BaseHTTPMiddleware):
|
|
|
42
47
|
async def dispatch(self, request: Request, call_next) -> Response:
|
|
43
48
|
_logger = logger.opt(colors=True, record=True)
|
|
44
49
|
|
|
45
|
-
_http_info:
|
|
50
|
+
_http_info: dict[str, Any] = {}
|
|
46
51
|
if hasattr(request.state, "http_info") and isinstance(
|
|
47
52
|
request.state.http_info, dict
|
|
48
53
|
):
|
|
49
|
-
_http_info:
|
|
54
|
+
_http_info: dict[str, Any] = request.state.http_info
|
|
50
55
|
|
|
51
|
-
|
|
56
|
+
# Debug log:
|
|
52
57
|
if self.use_debug_log:
|
|
53
58
|
_debug_msg = self.debug_format.format(**_http_info)
|
|
54
59
|
|
|
@@ -57,18 +62,18 @@ class HttpAccessLogMiddleware(BaseHTTPMiddleware):
|
|
|
57
62
|
_logger.debug,
|
|
58
63
|
_debug_msg,
|
|
59
64
|
)
|
|
60
|
-
|
|
65
|
+
# Debug log
|
|
61
66
|
|
|
62
|
-
|
|
67
|
+
# Process request:
|
|
63
68
|
response: Response = await call_next(request)
|
|
64
|
-
|
|
69
|
+
# Response processed.
|
|
65
70
|
|
|
66
71
|
if hasattr(request.state, "http_info") and isinstance(
|
|
67
72
|
request.state.http_info, dict
|
|
68
73
|
):
|
|
69
|
-
_http_info:
|
|
74
|
+
_http_info: dict[str, Any] = request.state.http_info
|
|
70
75
|
|
|
71
|
-
|
|
76
|
+
# Http access log:
|
|
72
77
|
_LEVEL = "INFO"
|
|
73
78
|
_msg_format = self.msg_format
|
|
74
79
|
if _http_info["status_code"] < 200:
|
|
@@ -92,9 +97,11 @@ class HttpAccessLogMiddleware(BaseHTTPMiddleware):
|
|
|
92
97
|
_msg = _msg_format.format(**_http_info)
|
|
93
98
|
# _logger.bind(http_info=_http_info).log(_LEVEL, _msg)
|
|
94
99
|
await run_in_threadpool(_logger.bind(http_info=_http_info).log, _LEVEL, _msg)
|
|
95
|
-
|
|
100
|
+
# Http access log
|
|
96
101
|
|
|
97
102
|
return response
|
|
98
103
|
|
|
99
104
|
|
|
100
|
-
__all__ = [
|
|
105
|
+
__all__ = [
|
|
106
|
+
"HttpAccessLogMiddleware",
|
|
107
|
+
]
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
if TYPE_CHECKING:
|
|
4
|
+
from loguru import Record
|
|
2
5
|
|
|
3
6
|
from beans_logging.filters import use_all_filter
|
|
4
7
|
|
|
5
8
|
|
|
6
|
-
def use_http_filter(record:
|
|
9
|
+
def use_http_filter(record: "Record") -> bool:
|
|
7
10
|
"""Filter message only for http access log handler by checking 'http_info' key in extra.
|
|
8
11
|
|
|
9
12
|
Args:
|
|
10
|
-
record (
|
|
13
|
+
record (Record, required): Log record as dictionary.
|
|
11
14
|
|
|
12
15
|
Returns:
|
|
13
16
|
bool: True if record has 'http_info' key in extra, False otherwise.
|
|
@@ -22,4 +25,6 @@ def use_http_filter(record: dict) -> bool:
|
|
|
22
25
|
return True
|
|
23
26
|
|
|
24
27
|
|
|
25
|
-
__all__ = [
|
|
28
|
+
__all__ = [
|
|
29
|
+
"use_http_filter",
|
|
30
|
+
]
|
|
@@ -1,18 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
from typing import Dict, Any
|
|
1
|
+
import json
|
|
2
|
+
from typing import Any
|
|
4
3
|
from zoneinfo import ZoneInfo
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from loguru import Record
|
|
5
8
|
|
|
6
9
|
|
|
7
10
|
def http_file_format(
|
|
8
|
-
record:
|
|
9
|
-
msg_format: str =
|
|
11
|
+
record: "Record",
|
|
12
|
+
msg_format: str = (
|
|
13
|
+
'{client_host} {request_id} {user_id} [{datetime}] "{method} {url_path} HTTP/{http_version}" '
|
|
14
|
+
'{status_code} {content_length} "{h_referer}" "{h_user_agent}" {response_time}'
|
|
15
|
+
),
|
|
10
16
|
tz: str = "localtime",
|
|
11
17
|
) -> str:
|
|
12
18
|
"""Http access log file format.
|
|
13
19
|
|
|
14
20
|
Args:
|
|
15
|
-
record
|
|
21
|
+
record (Record, required): Log record as dictionary.
|
|
22
|
+
msg_format (str , optional): Log message format.
|
|
23
|
+
tz (str , optional): Timezone for datetime field. Defaults to 'localtime'.
|
|
16
24
|
|
|
17
25
|
Returns:
|
|
18
26
|
str: Format for http access log record.
|
|
@@ -21,43 +29,44 @@ def http_file_format(
|
|
|
21
29
|
if "http_info" not in record["extra"]:
|
|
22
30
|
return ""
|
|
23
31
|
|
|
24
|
-
if "http_message"
|
|
25
|
-
|
|
26
|
-
if "datetime" not in _http_info:
|
|
27
|
-
_dt = record["time"]
|
|
28
|
-
if tz != "localtime":
|
|
29
|
-
if not _dt.tzinfo:
|
|
30
|
-
_dt = _dt.replace(tzinfo=ZoneInfo("UTC"))
|
|
32
|
+
if "http_message" in record["extra"]:
|
|
33
|
+
del record["extra"]["http_message"]
|
|
31
34
|
|
|
32
|
-
|
|
35
|
+
_http_info: dict[str, Any] = record["extra"]["http_info"]
|
|
36
|
+
if "datetime" not in _http_info:
|
|
37
|
+
_dt = record["time"]
|
|
38
|
+
if tz != "localtime":
|
|
39
|
+
if not _dt.tzinfo:
|
|
40
|
+
_dt = _dt.replace(tzinfo=ZoneInfo("UTC"))
|
|
33
41
|
|
|
34
|
-
|
|
42
|
+
_dt = _dt.astimezone(ZoneInfo(tz))
|
|
35
43
|
|
|
36
|
-
|
|
37
|
-
_http_info["content_length"] = 0
|
|
44
|
+
_http_info["datetime"] = _dt.isoformat(timespec="milliseconds")
|
|
38
45
|
|
|
39
|
-
|
|
40
|
-
|
|
46
|
+
if "content_length" not in _http_info:
|
|
47
|
+
_http_info["content_length"] = 0
|
|
41
48
|
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
if "h_referer" not in _http_info:
|
|
50
|
+
_http_info["h_referer"] = "-"
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
if "h_user_agent" not in _http_info:
|
|
53
|
+
_http_info["h_user_agent"] = "-"
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
if "response_time" not in _http_info:
|
|
56
|
+
_http_info["response_time"] = 0
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
record["extra"]["http_info"] = _http_info
|
|
59
|
+
_msg = msg_format.format(**_http_info)
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
record["extra"]["http_message"] = _msg
|
|
62
|
+
return "{extra[http_message]}\n"
|
|
54
63
|
|
|
55
64
|
|
|
56
|
-
def http_file_json_format(record:
|
|
65
|
+
def http_file_json_format(record: "Record") -> str:
|
|
57
66
|
"""Http access json log file format.
|
|
58
67
|
|
|
59
68
|
Args:
|
|
60
|
-
record (
|
|
69
|
+
record (Record, required): Log record as dictionary.
|
|
61
70
|
|
|
62
71
|
Returns:
|
|
63
72
|
str: Format for http access json log record.
|
|
@@ -66,12 +75,21 @@ def http_file_json_format(record: dict) -> str:
|
|
|
66
75
|
if "http_info" not in record["extra"]:
|
|
67
76
|
return ""
|
|
68
77
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
78
|
+
if "datetime" not in record["extra"]["http_info"]:
|
|
79
|
+
record["extra"]["http_info"]["datetime"] = record["time"].isoformat(
|
|
80
|
+
timespec="milliseconds"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
if "http_serialized" in record["extra"]:
|
|
84
|
+
del record["extra"]["http_serialized"]
|
|
85
|
+
|
|
86
|
+
_http_info = record["extra"]["http_info"]
|
|
87
|
+
record["extra"]["http_serialized"] = json.dumps(_http_info)
|
|
73
88
|
|
|
74
|
-
return "{extra[
|
|
89
|
+
return "{extra[http_serialized]}\n"
|
|
75
90
|
|
|
76
91
|
|
|
77
|
-
__all__ = [
|
|
92
|
+
__all__ = [
|
|
93
|
+
"http_file_format",
|
|
94
|
+
"http_file_json_format",
|
|
95
|
+
]
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
from collections.abc import Callable
|
|
2
2
|
|
|
3
|
-
from
|
|
4
|
-
|
|
5
|
-
import pydantic
|
|
6
|
-
|
|
7
|
-
if "2.0.0" <= pydantic.__version__:
|
|
8
|
-
from pydantic import validate_call
|
|
9
|
-
else:
|
|
10
|
-
from pydantic import validate_arguments as validate_call
|
|
3
|
+
from pydantic import validate_call
|
|
11
4
|
|
|
12
5
|
from beans_logging import LoggerLoader
|
|
13
6
|
|
|
@@ -15,13 +8,13 @@ from ._filters import use_http_filter
|
|
|
15
8
|
from ._formats import http_file_format, http_file_json_format
|
|
16
9
|
|
|
17
10
|
|
|
18
|
-
@validate_call(config=
|
|
11
|
+
@validate_call(config={"arbitrary_types_allowed": True})
|
|
19
12
|
def add_http_file_handler(
|
|
20
13
|
logger_loader: LoggerLoader,
|
|
21
14
|
log_path: str = "http/{app_name}.http.access.log",
|
|
22
15
|
err_path: str = "http/{app_name}.http.err.log",
|
|
23
|
-
formatter:
|
|
24
|
-
):
|
|
16
|
+
formatter: Callable | str = http_file_format,
|
|
17
|
+
) -> None:
|
|
25
18
|
"""Add http access log file and error file handler.
|
|
26
19
|
|
|
27
20
|
Args:
|
|
@@ -31,52 +24,73 @@ def add_http_file_handler(
|
|
|
31
24
|
formatter (Union[Callable, str], optional): Log formatter. Defaults to `http_file_format` function.
|
|
32
25
|
"""
|
|
33
26
|
|
|
34
|
-
logger_loader.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
logger_loader.add_handler(
|
|
28
|
+
name="default.http.access.file_handler",
|
|
29
|
+
handler={
|
|
30
|
+
"type": "FILE",
|
|
31
|
+
"sink": log_path,
|
|
32
|
+
"filter": use_http_filter,
|
|
33
|
+
"format": formatter,
|
|
34
|
+
},
|
|
39
35
|
)
|
|
40
36
|
|
|
41
|
-
logger_loader.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
logger_loader.add_handler(
|
|
38
|
+
name="default.http.err.file_handler",
|
|
39
|
+
handler={
|
|
40
|
+
"type": "FILE",
|
|
41
|
+
"sink": err_path,
|
|
42
|
+
"filter": use_http_filter,
|
|
43
|
+
"format": formatter,
|
|
44
|
+
"error": True,
|
|
45
|
+
},
|
|
47
46
|
)
|
|
48
47
|
|
|
48
|
+
return
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
|
|
51
|
+
@validate_call(config={"arbitrary_types_allowed": True})
|
|
51
52
|
def add_http_file_json_handler(
|
|
52
53
|
logger_loader: LoggerLoader,
|
|
53
|
-
log_path: str = "json
|
|
54
|
-
err_path: str = "json
|
|
55
|
-
formatter:
|
|
56
|
-
):
|
|
54
|
+
log_path: str = "http.json/{app_name}.http.json.access.log",
|
|
55
|
+
err_path: str = "http.json/{app_name}.http.json.err.log",
|
|
56
|
+
formatter: Callable | str = http_file_json_format,
|
|
57
|
+
) -> None:
|
|
57
58
|
"""Add http access json log file and json error file handler.
|
|
58
59
|
|
|
59
60
|
Args:
|
|
60
61
|
logger_loader (LoggerLoader, required): LoggerLoader instance.
|
|
61
|
-
log_path (str, optional): Json log file path. Defaults to
|
|
62
|
-
|
|
62
|
+
log_path (str, optional): Json log file path. Defaults to
|
|
63
|
+
"http.json/{app_name}.http.json.access.log".
|
|
64
|
+
err_path (str, optional): Json error log file path. Defaults to
|
|
65
|
+
"http.json/{app_name}.http.json.err.log".
|
|
63
66
|
formatter (Union[Callable, str], optional): Log formatter. Defaults to `http_file_json_format` function.
|
|
64
67
|
"""
|
|
65
68
|
|
|
66
|
-
logger_loader.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
logger_loader.add_handler(
|
|
70
|
+
name="default.http.access.json_handler",
|
|
71
|
+
handler={
|
|
72
|
+
"type": "FILE",
|
|
73
|
+
"sink": log_path,
|
|
74
|
+
"filter": use_http_filter,
|
|
75
|
+
"format": formatter,
|
|
76
|
+
},
|
|
71
77
|
)
|
|
72
78
|
|
|
73
|
-
logger_loader.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
+
logger_loader.add_handler(
|
|
80
|
+
name="default.http.err.json_handler",
|
|
81
|
+
handler={
|
|
82
|
+
"type": "FILE",
|
|
83
|
+
"sink": err_path,
|
|
84
|
+
"filter": use_http_filter,
|
|
85
|
+
"format": formatter,
|
|
86
|
+
"error": True,
|
|
87
|
+
},
|
|
79
88
|
)
|
|
80
89
|
|
|
90
|
+
return
|
|
91
|
+
|
|
81
92
|
|
|
82
|
-
__all__ = [
|
|
93
|
+
__all__ = [
|
|
94
|
+
"add_http_file_handler",
|
|
95
|
+
"add_http_file_json_handler",
|
|
96
|
+
]
|