##// END OF EJS Templates
deps: removed pinned deps in favor of moving them back into the requirements.txt file itself
super-admin -
r1058:2b749a9a python3
parent child Browse files
Show More
@@ -1,93 +1,93 b''
1
1
2 # set by: PATH_TO_OUTDATED_PACKAGES=/some/path/outdated_packages.py
2 # set by: PATH_TO_OUTDATED_PACKAGES=/some/path/outdated_packages.py
3 OUTDATED_PACKAGES = ${PATH_TO_OUTDATED_PACKAGES}
3 OUTDATED_PACKAGES = ${PATH_TO_OUTDATED_PACKAGES}
4
4
5 .PHONY: clean
5 .PHONY: clean
6 ## Cleanup compiled and cache py files
6 ## Cleanup compiled and cache py files
7 clean:
7 clean:
8 make test-clean
8 make test-clean
9 find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' -o -iname '*.orig' \) -exec rm '{}' ';'
9 find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' -o -iname '*.orig' \) -exec rm '{}' ';'
10
10
11
11
12 .PHONY: test
12 .PHONY: test
13 ## run test-clean and tests
13 ## run test-clean and tests
14 test:
14 test:
15 make test-clean
15 make test-clean
16 make test-only
16 make test-only
17
17
18
18
19 .PHONY:test-clean
19 .PHONY:test-clean
20 ## run test-clean and tests
20 ## run test-clean and tests
21 test-clean:
21 test-clean:
22 rm -rf coverage.xml htmlcov junit.xml pylint.log result
22 rm -rf coverage.xml htmlcov junit.xml pylint.log result
23 find . -type d -name "__pycache__" -prune -exec rm -rf '{}' ';'
23 find . -type d -name "__pycache__" -prune -exec rm -rf '{}' ';'
24 find . -type f \( -iname '.coverage.*' \) -exec rm '{}' ';'
24 find . -type f \( -iname '.coverage.*' \) -exec rm '{}' ';'
25
25
26
26
27 .PHONY: test-only
27 .PHONY: test-only
28 ## Run tests only without cleanup
28 ## Run tests only without cleanup
29 test-only:
29 test-only:
30 PYTHONHASHSEED=random \
30 PYTHONHASHSEED=random \
31 py.test -x -vv -r xw -p no:sugar \
31 py.test -x -vv -r xw -p no:sugar \
32 --cov-report=term-missing --cov-report=html --cov=vcsserver vcsserver
32 --cov-report=term-missing --cov-report=html --cov=vcsserver vcsserver
33
33
34
34
35
35
36 .PHONY: pip-packages
36 .PHONY: pip-packages
37 ## Show outdated packages
37 ## Show outdated packages
38 pip-packages:
38 pip-packages:
39 python ${OUTDATED_PACKAGES}
39 python ${OUTDATED_PACKAGES}
40
40
41
41
42 .PHONY: sdist
42 .PHONY: sdist
43 ## Build sdist
43 ## Build sdist
44 sdist:
44 sdist:
45 python setup.py sdist
45 python setup.py sdist
46
46
47 .PHONY: dev-env
47 .PHONY: dev-env
48 ## Build sdist
48 ## Build sdist
49 dev-env:
49 dev-env:
50 pip install -r requirements.txt -r requirements_pinned.txt -r requirements_debug.txt -r requirements_test.txt
50 pip install -r requirements.txt -r requirements_debug.txt -r requirements_test.txt
51 pip install -e .
51 pip install -e .
52
52
53 # Default command on calling make
53 # Default command on calling make
54 .DEFAULT_GOAL := show-help
54 .DEFAULT_GOAL := show-help
55
55
56 .PHONY: show-help
56 .PHONY: show-help
57 show-help:
57 show-help:
58 @echo "$$(tput bold)Available rules:$$(tput sgr0)"
58 @echo "$$(tput bold)Available rules:$$(tput sgr0)"
59 @echo
59 @echo
60 @sed -n -e "/^## / { \
60 @sed -n -e "/^## / { \
61 h; \
61 h; \
62 s/.*//; \
62 s/.*//; \
63 :doc" \
63 :doc" \
64 -e "H; \
64 -e "H; \
65 n; \
65 n; \
66 s/^## //; \
66 s/^## //; \
67 t doc" \
67 t doc" \
68 -e "s/:.*//; \
68 -e "s/:.*//; \
69 G; \
69 G; \
70 s/\\n## /---/; \
70 s/\\n## /---/; \
71 s/\\n/ /g; \
71 s/\\n/ /g; \
72 p; \
72 p; \
73 }" ${MAKEFILE_LIST} \
73 }" ${MAKEFILE_LIST} \
74 | LC_ALL='C' sort --ignore-case \
74 | LC_ALL='C' sort --ignore-case \
75 | awk -F '---' \
75 | awk -F '---' \
76 -v ncol=$$(tput cols) \
76 -v ncol=$$(tput cols) \
77 -v indent=19 \
77 -v indent=19 \
78 -v col_on="$$(tput setaf 6)" \
78 -v col_on="$$(tput setaf 6)" \
79 -v col_off="$$(tput sgr0)" \
79 -v col_off="$$(tput sgr0)" \
80 '{ \
80 '{ \
81 printf "%s%*s%s ", col_on, -indent, $$1, col_off; \
81 printf "%s%*s%s ", col_on, -indent, $$1, col_off; \
82 n = split($$2, words, " "); \
82 n = split($$2, words, " "); \
83 line_length = ncol - indent; \
83 line_length = ncol - indent; \
84 for (i = 1; i <= n; i++) { \
84 for (i = 1; i <= n; i++) { \
85 line_length -= length(words[i]) + 1; \
85 line_length -= length(words[i]) + 1; \
86 if (line_length <= 0) { \
86 if (line_length <= 0) { \
87 line_length = ncol - indent - length(words[i]) - 1; \
87 line_length = ncol - indent - length(words[i]) - 1; \
88 printf "\n%*s ", -indent, " "; \
88 printf "\n%*s ", -indent, " "; \
89 } \
89 } \
90 printf "%s ", words[i]; \
90 printf "%s ", words[i]; \
91 } \
91 } \
92 printf "\n"; \
92 printf "\n"; \
93 }'
93 }'
@@ -1,42 +1,62 b''
1 ## dependencies
1 ## dependencies
2
2
3 configobj==5.0.8
3 configobj==5.0.8
4
4
5 dogpile.cache==1.1.8
5 dogpile.cache==1.1.8
6
6
7 decorator==5.1.1
7 decorator==5.1.1
8 dulwich==0.21.3
8 dulwich==0.21.3
9 hg-evolve==11.0.0
9 hg-evolve==11.0.0
10
10
11 mercurial==6.3.3
11 mercurial==6.3.3
12 msgpack-python==0.5.6
12 msgpack-python==0.5.6
13 more-itertools==9.1.0
13 more-itertools==9.1.0
14
14
15 pastedeploy==3.0.1
15 pastedeploy==3.0.1
16 pyramid==2.0.1
16 pyramid==2.0.1
17 pygit2==1.11.1
17 pygit2==1.11.1
18
18
19 repoze.lru==0.7
19 repoze.lru==0.7
20 redis==4.5.1
20 redis==4.5.1
21 simplejson==3.18.3
21 simplejson==3.18.3
22 subvertpy==0.11.0
22 subvertpy==0.11.0
23
23
24 translationstring==1.4
24 translationstring==1.4
25 webob==1.8.7
25 webob==1.8.7
26 zope.deprecation==4.4.0
26 zope.deprecation==4.4.0
27 zope.interface==5.5.2
27 zope.interface==5.5.2
28
28
29 ## http servers
29 ## http servers
30 #gevent==20.6.0
30 #gevent==20.6.0
31 #greenlet==0.4.16
31 #greenlet==0.4.16
32 gunicorn==20.1.0
32 gunicorn==20.1.0
33 waitress==2.1.2
33 waitress==2.1.2
34
34
35 # contains not directly required libraries we want to pin the version.
36
37 atomicwrites==1.4.1
38 attrs==22.2.0
39 contextlib2==21.6.0
40 cffi==1.15.1
41 hupper==1.11
42 importlib-metadata==6.0.0
43 packaging==23.0
44 pathlib2==2.3.7.post1
45 pygments==2.14.0
46 pyparsing==3.0.9
47 psutil==5.9.4
48 pluggy==1.0.0
49 scandir==1.10.0
50 setproctitle==1.3.2
51 venusian==3.0.0
52 wcwidth==0.2.6
53 toml==0.10.2
54
35 ## test related requirements
55 ## test related requirements
36 -r requirements_test.txt
56 -r requirements_test.txt
37
57
38 ## uncomment to add the debug libraries
58 ## uncomment to add the debug libraries
39 #ipdb==0.13.2
59 #ipdb==0.13.2
40 #ipython==7.15.0
60 #ipython==7.15.0
41
61
42 #-r requirements_debug.txt
62 #-r requirements_debug.txt
@@ -1,243 +1,243 b''
1 '''
1 '''
2 This library is provided to allow standard python logging
2 This library is provided to allow standard python logging
3 to output log data as JSON formatted strings
3 to output log data as JSON formatted strings
4 '''
4 '''
5 import logging
5 import logging
6 import json
6 import json
7 import re
7 import re
8 from datetime import date, datetime, time, tzinfo, timedelta
8 from datetime import date, datetime, time, tzinfo, timedelta
9 import traceback
9 import traceback
10 import importlib
10 import importlib
11
11
12 from inspect import istraceback
12 from inspect import istraceback
13
13
14 from collections import OrderedDict
14 from collections import OrderedDict
15
15
16
16
17 def _inject_req_id(record, *args, **kwargs):
17 def _inject_req_id(record, *args, **kwargs):
18 return record
18 return record
19
19
20
20
21 ExceptionAwareFormatter = logging.Formatter
21 ExceptionAwareFormatter = logging.Formatter
22
22
23
23
24 ZERO = timedelta(0)
24 ZERO = timedelta(0)
25 HOUR = timedelta(hours=1)
25 HOUR = timedelta(hours=1)
26
26
27
27
28 class UTC(tzinfo):
28 class UTC(tzinfo):
29 """UTC"""
29 """UTC"""
30
30
31 def utcoffset(self, dt):
31 def utcoffset(self, dt):
32 return ZERO
32 return ZERO
33
33
34 def tzname(self, dt):
34 def tzname(self, dt):
35 return "UTC"
35 return "UTC"
36
36
37 def dst(self, dt):
37 def dst(self, dt):
38 return ZERO
38 return ZERO
39
39
40 utc = UTC()
40 utc = UTC()
41
41
42
42
43 # skip natural LogRecord attributes
43 # skip natural LogRecord attributes
44 # http://docs.python.org/library/logging.html#logrecord-attributes
44 # http://docs.python.org/library/logging.html#logrecord-attributes
45 RESERVED_ATTRS = (
45 RESERVED_ATTRS = (
46 'args', 'asctime', 'created', 'exc_info', 'exc_text', 'filename',
46 'args', 'asctime', 'created', 'exc_info', 'exc_text', 'filename',
47 'funcName', 'levelname', 'levelno', 'lineno', 'module',
47 'funcName', 'levelname', 'levelno', 'lineno', 'module',
48 'msecs', 'message', 'msg', 'name', 'pathname', 'process',
48 'msecs', 'message', 'msg', 'name', 'pathname', 'process',
49 'processName', 'relativeCreated', 'stack_info', 'thread', 'threadName')
49 'processName', 'relativeCreated', 'stack_info', 'thread', 'threadName')
50
50
51
51
52 def merge_record_extra(record, target, reserved):
52 def merge_record_extra(record, target, reserved):
53 """
53 """
54 Merges extra attributes from LogRecord object into target dictionary
54 Merges extra attributes from LogRecord object into target dictionary
55
55
56 :param record: logging.LogRecord
56 :param record: logging.LogRecord
57 :param target: dict to update
57 :param target: dict to update
58 :param reserved: dict or list with reserved keys to skip
58 :param reserved: dict or list with reserved keys to skip
59 """
59 """
60 for key, value in record.__dict__.items():
60 for key, value in record.__dict__.items():
61 # this allows to have numeric keys
61 # this allows to have numeric keys
62 if (key not in reserved
62 if (key not in reserved
63 and not (hasattr(key, "startswith")
63 and not (hasattr(key, "startswith")
64 and key.startswith('_'))):
64 and key.startswith('_'))):
65 target[key] = value
65 target[key] = value
66 return target
66 return target
67
67
68
68
69 class JsonEncoder(json.JSONEncoder):
69 class JsonEncoder(json.JSONEncoder):
70 """
70 """
71 A custom encoder extending the default JSONEncoder
71 A custom encoder extending the default JSONEncoder
72 """
72 """
73
73
74 def default(self, obj):
74 def default(self, obj):
75 if isinstance(obj, (date, datetime, time)):
75 if isinstance(obj, (date, datetime, time)):
76 return self.format_datetime_obj(obj)
76 return self.format_datetime_obj(obj)
77
77
78 elif istraceback(obj):
78 elif istraceback(obj):
79 return ''.join(traceback.format_tb(obj)).strip()
79 return ''.join(traceback.format_tb(obj)).strip()
80
80
81 elif type(obj) == Exception \
81 elif type(obj) == Exception \
82 or isinstance(obj, Exception) \
82 or isinstance(obj, Exception) \
83 or type(obj) == type:
83 or type(obj) == type:
84 return str(obj)
84 return str(obj)
85
85
86 try:
86 try:
87 return super(JsonEncoder, self).default(obj)
87 return super(JsonEncoder, self).default(obj)
88
88
89 except TypeError:
89 except TypeError:
90 try:
90 try:
91 return str(obj)
91 return str(obj)
92
92
93 except Exception:
93 except Exception:
94 return None
94 return None
95
95
96 def format_datetime_obj(self, obj):
96 def format_datetime_obj(self, obj):
97 return obj.isoformat()
97 return obj.isoformat()
98
98
99
99
100 class JsonFormatter(ExceptionAwareFormatter):
100 class JsonFormatter(ExceptionAwareFormatter):
101 """
101 """
102 A custom formatter to format logging records as json strings.
102 A custom formatter to format logging records as json strings.
103 Extra values will be formatted as str() if not supported by
103 Extra values will be formatted as str() if not supported by
104 json default encoder
104 json default encoder
105 """
105 """
106
106
107 def __init__(self, *args, **kwargs):
107 def __init__(self, *args, **kwargs):
108 """
108 """
109 :param json_default: a function for encoding non-standard objects
109 :param json_default: a function for encoding non-standard objects
110 as outlined in http://docs.python.org/2/library/json.html
110 as outlined in http://docs.python.org/2/library/json.html
111 :param json_encoder: optional custom encoder
111 :param json_encoder: optional custom encoder
112 :param json_serializer: a :meth:`json.dumps`-compatible callable
112 :param json_serializer: a :meth:`json.dumps`-compatible callable
113 that will be used to serialize the log record.
113 that will be used to serialize the log record.
114 :param json_indent: an optional :meth:`json.dumps`-compatible numeric value
114 :param json_indent: an optional :meth:`json.dumps`-compatible numeric value
115 that will be used to customize the indent of the output json.
115 that will be used to customize the indent of the output json.
116 :param prefix: an optional string prefix added at the beginning of
116 :param prefix: an optional string prefix added at the beginning of
117 the formatted string
117 the formatted string
118 :param json_indent: indent parameter for json.dumps
118 :param json_indent: indent parameter for json.dumps
119 :param json_ensure_ascii: ensure_ascii parameter for json.dumps
119 :param json_ensure_ascii: ensure_ascii parameter for json.dumps
120 :param reserved_attrs: an optional list of fields that will be skipped when
120 :param reserved_attrs: an optional list of fields that will be skipped when
121 outputting json log record. Defaults to all log record attributes:
121 outputting json log record. Defaults to all log record attributes:
122 http://docs.python.org/library/logging.html#logrecord-attributes
122 http://docs.python.org/library/logging.html#logrecord-attributes
123 :param timestamp: an optional string/boolean field to add a timestamp when
123 :param timestamp: an optional string/boolean field to add a timestamp when
124 outputting the json log record. If string is passed, timestamp will be added
124 outputting the json log record. If string is passed, timestamp will be added
125 to log record using string as key. If True boolean is passed, timestamp key
125 to log record using string as key. If True boolean is passed, timestamp key
126 will be "timestamp". Defaults to False/off.
126 will be "timestamp". Defaults to False/off.
127 """
127 """
128 self.json_default = self._str_to_fn(kwargs.pop("json_default", None))
128 self.json_default = self._str_to_fn(kwargs.pop("json_default", None))
129 self.json_encoder = self._str_to_fn(kwargs.pop("json_encoder", None))
129 self.json_encoder = self._str_to_fn(kwargs.pop("json_encoder", None))
130 self.json_serializer = self._str_to_fn(kwargs.pop("json_serializer", json.dumps))
130 self.json_serializer = self._str_to_fn(kwargs.pop("json_serializer", json.dumps))
131 self.json_indent = kwargs.pop("json_indent", None)
131 self.json_indent = kwargs.pop("json_indent", None)
132 self.json_ensure_ascii = kwargs.pop("json_ensure_ascii", True)
132 self.json_ensure_ascii = kwargs.pop("json_ensure_ascii", True)
133 self.prefix = kwargs.pop("prefix", "")
133 self.prefix = kwargs.pop("prefix", "")
134 reserved_attrs = kwargs.pop("reserved_attrs", RESERVED_ATTRS)
134 reserved_attrs = kwargs.pop("reserved_attrs", RESERVED_ATTRS)
135 self.reserved_attrs = dict(list(zip(reserved_attrs, reserved_attrs)))
135 self.reserved_attrs = dict(list(zip(reserved_attrs, reserved_attrs)))
136 self.timestamp = kwargs.pop("timestamp", True)
136 self.timestamp = kwargs.pop("timestamp", True)
137
137
138 # super(JsonFormatter, self).__init__(*args, **kwargs)
138 # super(JsonFormatter, self).__init__(*args, **kwargs)
139 logging.Formatter.__init__(self, *args, **kwargs)
139 logging.Formatter.__init__(self, *args, **kwargs)
140 if not self.json_encoder and not self.json_default:
140 if not self.json_encoder and not self.json_default:
141 self.json_encoder = JsonEncoder
141 self.json_encoder = JsonEncoder
142
142
143 self._required_fields = self.parse()
143 self._required_fields = self.parse()
144 self._skip_fields = dict(list(zip(self._required_fields,
144 self._skip_fields = dict(list(zip(self._required_fields,
145 self._required_fields)))
145 self._required_fields)))
146 self._skip_fields.update(self.reserved_attrs)
146 self._skip_fields.update(self.reserved_attrs)
147
147
148 def _str_to_fn(self, fn_as_str):
148 def _str_to_fn(self, fn_as_str):
149 """
149 """
150 If the argument is not a string, return whatever was passed in.
150 If the argument is not a string, return whatever was passed in.
151 Parses a string such as package.module.function, imports the module
151 Parses a string such as package.module.function, imports the module
152 and returns the function.
152 and returns the function.
153
153
154 :param fn_as_str: The string to parse. If not a string, return it.
154 :param fn_as_str: The string to parse. If not a string, return it.
155 """
155 """
156 if not isinstance(fn_as_str, str):
156 if not isinstance(fn_as_str, str):
157 return fn_as_str
157 return fn_as_str
158
158
159 path, _, function = fn_as_str.rpartition('.')
159 path, _, function = fn_as_str.rpartition('.')
160 module = importlib.import_module(path)
160 module = importlib.import_module(path)
161 return getattr(module, function)
161 return getattr(module, function)
162
162
163 def parse(self):
163 def parse(self):
164 """
164 """
165 Parses format string looking for substitutions
165 Parses format string looking for substitutions
166
166
167 This method is responsible for returning a list of fields (as strings)
167 This method is responsible for returning a list of fields (as strings)
168 to include in all log messages.
168 to include in all log messages.
169 """
169 """
170 standard_formatters = re.compile(r'\((.+?)\)', re.IGNORECASE)
170 standard_formatters = re.compile(r'\((.+?)\)', re.IGNORECASE)
171 return standard_formatters.findall(self._fmt)
171 return standard_formatters.findall(self._fmt)
172
172
173 def add_fields(self, log_record, record, message_dict):
173 def add_fields(self, log_record, record, message_dict):
174 """
174 """
175 Override this method to implement custom logic for adding fields.
175 Override this method to implement custom logic for adding fields.
176 """
176 """
177 for field in self._required_fields:
177 for field in self._required_fields:
178 log_record[field] = record.__dict__.get(field)
178 log_record[field] = record.__dict__.get(field)
179 log_record.update(message_dict)
179 log_record.update(message_dict)
180 merge_record_extra(record, log_record, reserved=self._skip_fields)
180 merge_record_extra(record, log_record, reserved=self._skip_fields)
181
181
182 if self.timestamp:
182 if self.timestamp:
183 key = self.timestamp if type(self.timestamp) == str else 'timestamp'
183 key = self.timestamp if type(self.timestamp) == str else 'timestamp'
184 log_record[key] = datetime.fromtimestamp(record.created, tz=utc)
184 log_record[key] = datetime.fromtimestamp(record.created, tz=utc)
185
185
186 def process_log_record(self, log_record):
186 def process_log_record(self, log_record):
187 """
187 """
188 Override this method to implement custom logic
188 Override this method to implement custom logic
189 on the possibly ordered dictionary.
189 on the possibly ordered dictionary.
190 """
190 """
191 return log_record
191 return log_record
192
192
193 def jsonify_log_record(self, log_record):
193 def jsonify_log_record(self, log_record):
194 """Returns a json string of the log record."""
194 """Returns a json string of the log record."""
195 return self.json_serializer(log_record,
195 return self.json_serializer(log_record,
196 default=self.json_default,
196 default=self.json_default,
197 cls=self.json_encoder,
197 cls=self.json_encoder,
198 indent=self.json_indent,
198 indent=self.json_indent,
199 ensure_ascii=self.json_ensure_ascii)
199 ensure_ascii=self.json_ensure_ascii)
200
200
201 def serialize_log_record(self, log_record):
201 def serialize_log_record(self, log_record):
202 """Returns the final representation of the log record."""
202 """Returns the final representation of the log record."""
203 return "%s%s" % (self.prefix, self.jsonify_log_record(log_record))
203 return "%s%s" % (self.prefix, self.jsonify_log_record(log_record))
204
204
205 def format(self, record):
205 def format(self, record):
206 """Formats a log record and serializes to json"""
206 """Formats a log record and serializes to json"""
207 message_dict = {}
207 message_dict = {}
208 # FIXME: logging.LogRecord.msg and logging.LogRecord.message in typeshed
208 # FIXME: logging.LogRecord.msg and logging.LogRecord.message in typeshed
209 # are always type of str. We shouldn't need to override that.
209 # are always type of str. We shouldn't need to override that.
210 if isinstance(record.msg, dict):
210 if isinstance(record.msg, dict):
211 message_dict = record.msg
211 message_dict = record.msg
212 record.message = None
212 record.message = None
213 else:
213 else:
214 record.message = record.getMessage()
214 record.message = record.getMessage()
215 # only format time if needed
215 # only format time if needed
216 if "asctime" in self._required_fields:
216 if "asctime" in self._required_fields:
217 record.asctime = self.formatTime(record, self.datefmt)
217 record.asctime = self.formatTime(record, self.datefmt)
218
218
219 # Display formatted exception, but allow overriding it in the
219 # Display formatted exception, but allow overriding it in the
220 # user-supplied dict.
220 # user-supplied dict.
221 if record.exc_info and not message_dict.get('exc_info'):
221 if record.exc_info and not message_dict.get('exc_info'):
222 message_dict['exc_info'] = self.formatException(record.exc_info)
222 message_dict['exc_info'] = self.formatException(record.exc_info)
223 if not message_dict.get('exc_info') and record.exc_text:
223 if not message_dict.get('exc_info') and record.exc_text:
224 message_dict['exc_info'] = record.exc_text
224 message_dict['exc_info'] = record.exc_text
225 # Display formatted record of stack frames
225 # Display formatted record of stack frames
226 # default format is a string returned from :func:`traceback.print_stack`
226 # default format is a string returned from :func:`traceback.print_stack`
227 try:
227 try:
228 if record.stack_info and not message_dict.get('stack_info'):
228 if record.stack_info and not message_dict.get('stack_info'):
229 message_dict['stack_info'] = self.formatStack(record.stack_info)
229 message_dict['stack_info'] = self.formatStack(record.stack_info)
230 except AttributeError:
230 except AttributeError:
231 # Python2.7 doesn't have stack_info.
231 # Python2.7 doesn't have stack_info.
232 pass
232 pass
233
233
234 try:
234 try:
235 log_record = OrderedDict()
235 log_record = OrderedDict()
236 except NameError:
236 except NameError:
237 log_record = {}
237 log_record = {}
238
238
239 _inject_req_id(record, with_prefix=False)
239 _inject_req_id(record, with_prefix=False)
240 self.add_fields(log_record, record, message_dict)
240 self.add_fields(log_record, record, message_dict)
241 log_record = self.process_log_record(log_record)
241 log_record = self.process_log_record(log_record)
242
242
243 return self.serialize_log_record(log_record)
243 return self.serialize_log_record(log_record)
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now