15
15
# specific language governing permissions and limitations
16
16
# under the License.
17
17
18
+ import collections .abc
18
19
import logging
19
20
import sys
20
21
import time
22
+ from functools import lru_cache
21
23
from traceback import format_tb
22
24
23
25
from ._meta import ECS_VERSION
24
26
from ._utils import (
25
- TYPE_CHECKING ,
26
- collections_abc ,
27
27
de_dot ,
28
28
flatten_dict ,
29
29
json_dumps ,
30
- lru_cache ,
31
30
merge_dicts ,
32
31
)
33
32
34
- if TYPE_CHECKING :
35
- from typing import Any , Callable , Dict , Optional , Sequence
33
+ from typing import Any , Callable , Dict , Optional , Sequence , Union
36
34
37
- try :
38
- from typing import Literal , Union # type: ignore
39
- except ImportError :
40
- from typing_extensions import Literal , Union # type: ignore
35
+ try :
36
+ from typing import Literal # type: ignore
37
+ except ImportError :
38
+ from typing_extensions import Literal # type: ignore
41
39
42
40
43
41
# Load the attributes of a LogRecord so if some are
@@ -78,16 +76,15 @@ class StdlibFormatter(logging.Formatter):
78
76
converter = time .gmtime
79
77
80
78
def __init__ (
81
- self , # type: Any
82
- fmt = None , # type: Optional[str]
83
- datefmt = None , # type: Optional[str]
84
- style = "%" , # type: Union[Literal["%"], Literal["{"], Literal["$"]]
85
- validate = None , # type: Optional[bool]
86
- stack_trace_limit = None , # type: Optional[int]
87
- extra = None , # type: Optional[Dict[str, Any]]
88
- exclude_fields = (), # type: Sequence[str]
89
- ):
90
- # type: (...) -> None
79
+ self ,
80
+ fmt : Optional [str ] = None ,
81
+ datefmt : Optional [str ] = None ,
82
+ style : Union [Literal ["%" ], Literal ["{" ], Literal ["$" ]] = "%" ,
83
+ validate : Optional [bool ] = None ,
84
+ stack_trace_limit : Optional [int ] = None ,
85
+ extra : Optional [Dict [str , Any ]] = None ,
86
+ exclude_fields : Sequence [str ] = (),
87
+ ) -> None :
91
88
"""Initialize the ECS formatter.
92
89
93
90
:param int stack_trace_limit:
@@ -127,7 +124,7 @@ def __init__(
127
124
)
128
125
129
126
if (
130
- not isinstance (exclude_fields , collections_abc .Sequence )
127
+ not isinstance (exclude_fields , collections . abc .Sequence )
131
128
or isinstance (exclude_fields , str )
132
129
or any (not isinstance (item , str ) for item in exclude_fields )
133
130
):
@@ -137,8 +134,7 @@ def __init__(
137
134
self ._exclude_fields = frozenset (exclude_fields )
138
135
self ._stack_trace_limit = stack_trace_limit
139
136
140
- def _record_error_type (self , record ):
141
- # type: (logging.LogRecord) -> Optional[str]
137
+ def _record_error_type (self , record : logging .LogRecord ) -> Optional [str ]:
142
138
exc_info = record .exc_info
143
139
if not exc_info :
144
140
# exc_info is either an iterable or bool. If it doesn't
@@ -151,8 +147,7 @@ def _record_error_type(self, record):
151
147
return exc_info [0 ].__name__
152
148
return None
153
149
154
- def _record_error_message (self , record ):
155
- # type: (logging.LogRecord) -> Optional[str]
150
+ def _record_error_message (self , record : logging .LogRecord ) -> Optional [str ]:
156
151
exc_info = record .exc_info
157
152
if not exc_info :
158
153
# exc_info is either an iterable or bool. If it doesn't
@@ -165,13 +160,11 @@ def _record_error_message(self, record):
165
160
return str (exc_info [1 ])
166
161
return None
167
162
168
- def format (self , record ):
169
- # type: (logging.LogRecord) -> str
163
+ def format (self , record : logging .LogRecord ) -> str :
170
164
result = self .format_to_ecs (record )
171
165
return json_dumps (result )
172
166
173
- def format_to_ecs (self , record ):
174
- # type: (logging.LogRecord) -> Dict[str, Any]
167
+ def format_to_ecs (self , record : logging .LogRecord ) -> Dict [str , Any ]:
175
168
"""Function that can be overridden to add additional fields to
176
169
(or remove fields from) the JSON before being dumped into a string.
177
170
@@ -185,7 +178,7 @@ def format_to_ecs(self, record):
185
178
return result
186
179
"""
187
180
188
- extractors = {
181
+ extractors : Dict [ str , Callable [[ logging . LogRecord ], Any ]] = {
189
182
"@timestamp" : self ._record_timestamp ,
190
183
"ecs.version" : lambda _ : ECS_VERSION ,
191
184
"log.level" : lambda r : (r .levelname .lower () if r .levelname else None ),
@@ -201,9 +194,9 @@ def format_to_ecs(self, record):
201
194
"error.type" : self ._record_error_type ,
202
195
"error.message" : self ._record_error_message ,
203
196
"error.stack_trace" : self ._record_error_stack_trace ,
204
- } # type: Dict[str, Callable[[logging.LogRecord],Any]]
197
+ }
205
198
206
- result = {} # type : Dict[str, Any]
199
+ result : Dict [str , Any ] = {}
207
200
for field in set (extractors .keys ()).difference (self ._exclude_fields ):
208
201
if self ._is_field_excluded (field ):
209
202
continue
@@ -262,28 +255,26 @@ def format_to_ecs(self, record):
262
255
return result
263
256
264
257
@lru_cache ()
265
- def _is_field_excluded (self , field ):
266
- # type: (str) -> bool
258
+ def _is_field_excluded (self , field : str ) -> bool :
267
259
field_path = []
268
260
for path in field .split ("." ):
269
261
field_path .append (path )
270
262
if "." .join (field_path ) in self ._exclude_fields :
271
263
return True
272
264
return False
273
265
274
- def _record_timestamp (self , record ):
275
- # type: (logging.LogRecord) -> str
266
+ def _record_timestamp (self , record : logging .LogRecord ) -> str :
276
267
return "%s.%03dZ" % (
277
268
self .formatTime (record , datefmt = "%Y-%m-%dT%H:%M:%S" ),
278
269
record .msecs ,
279
270
)
280
271
281
- def _record_attribute (self , attribute ):
282
- # type: (str) -> Callable[[logging.LogRecord], Optional[Any]]
272
+ def _record_attribute (
273
+ self , attribute : str
274
+ ) -> Callable [[logging .LogRecord ], Optional [Any ]]:
283
275
return lambda r : getattr (r , attribute , None )
284
276
285
- def _record_error_stack_trace (self , record ):
286
- # type: (logging.LogRecord) -> Optional[str]
277
+ def _record_error_stack_trace (self , record : logging .LogRecord ) -> Optional [str ]:
287
278
# Using stack_info=True will add 'error.stack_trace' even
288
279
# if the type is not 'error', exc_info=True only gathers
289
280
# when there's an active exception.
0 commit comments