Skip to content

Commit 424c3c7

Browse files
authored
integrate logs (Azure#20300)
* integrate logs * update * update * update * update * Update _universal.py * update
1 parent cbdaf08 commit 424c3c7

File tree

9 files changed

+346
-245
lines changed

9 files changed

+346
-245
lines changed

sdk/core/azure-core/azure/core/pipeline/policies/_universal.py

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def on_request(self, request):
246246

247247

248248
class NetworkTraceLoggingPolicy(SansIOHTTPPolicy):
249+
249250
"""The logging policy in the pipeline is used to output HTTP network trace to the configured logger.
250251
251252
This accepts both global configuration, and per-request level with "enable_http_logger"
@@ -264,7 +265,7 @@ class NetworkTraceLoggingPolicy(SansIOHTTPPolicy):
264265
def __init__(self, logging_enable=False, **kwargs): # pylint: disable=unused-argument
265266
self.enable_http_logger = logging_enable
266267

267-
def on_request(self, request):
268+
def on_request(self, request): # pylint: disable=too-many-return-statements
268269
# type: (PipelineRequest) -> None
269270
"""Logs HTTP request to the DEBUG logger.
270271
@@ -280,27 +281,31 @@ def on_request(self, request):
280281
return
281282

282283
try:
283-
_LOGGER.debug("Request URL: %r", http_request.url)
284-
_LOGGER.debug("Request method: %r", http_request.method)
285-
_LOGGER.debug("Request headers:")
284+
log_string = "Request URL: '{}'".format(http_request.url)
285+
log_string += "/nRequest method: '{}'".format(http_request.method)
286+
log_string += "/nRequest headers:"
286287
for header, value in http_request.headers.items():
287-
_LOGGER.debug(" %r: %r", header, value)
288-
_LOGGER.debug("Request body:")
288+
log_string += "/n '{}': '{}'".format(header, value)
289+
log_string += "/nRequest body:"
289290

290291
# We don't want to log the binary data of a file upload.
291292
if isinstance(http_request.body, types.GeneratorType):
292-
_LOGGER.debug("File upload")
293+
log_string += "/nFile upload"
294+
_LOGGER.debug(log_string)
293295
return
294296
try:
295297
if isinstance(http_request.body, types.AsyncGeneratorType):
296-
_LOGGER.debug("File upload")
298+
log_string += "/nFile upload"
299+
_LOGGER.debug(log_string)
297300
return
298301
except AttributeError:
299302
pass
300303
if http_request.body:
301-
_LOGGER.debug(str(http_request.body))
304+
log_string += "/n{}".format(str(http_request.body))
305+
_LOGGER.debug(log_string)
302306
return
303-
_LOGGER.debug("This request has no body")
307+
log_string += "/nThis request has no body"
308+
_LOGGER.debug(log_string)
304309
except Exception as err: # pylint: disable=broad-except
305310
_LOGGER.debug("Failed to log request: %r", err)
306311

@@ -320,28 +325,29 @@ def on_response(self, request, response):
320325
if not _LOGGER.isEnabledFor(logging.DEBUG):
321326
return
322327

323-
_LOGGER.debug("Response status: %r", http_response.status_code)
324-
_LOGGER.debug("Response headers:")
328+
log_string = "Response status: '{}'".format(http_response.status_code)
329+
log_string += "/nResponse headers:"
325330
for res_header, value in http_response.headers.items():
326-
_LOGGER.debug(" %r: %r", res_header, value)
331+
log_string += "/n '{}': '{}'".format(res_header, value)
327332

328333
# We don't want to log binary data if the response is a file.
329-
_LOGGER.debug("Response content:")
334+
log_string += "/nResponse content:"
330335
pattern = re.compile(r'attachment; ?filename=["\w.]+', re.IGNORECASE)
331336
header = http_response.headers.get('content-disposition')
332337

333338
if header and pattern.match(header):
334339
filename = header.partition('=')[2]
335-
_LOGGER.debug("File attachments: %s", filename)
340+
log_string += "/nFile attachments: {}".format(filename)
336341
elif http_response.headers.get("content-type", "").endswith("octet-stream"):
337-
_LOGGER.debug("Body contains binary data.")
342+
log_string += "/nBody contains binary data."
338343
elif http_response.headers.get("content-type", "").startswith("image"):
339-
_LOGGER.debug("Body contains image data.")
344+
log_string += "/nBody contains image data."
340345
else:
341346
if response.context.options.get('stream', False):
342-
_LOGGER.debug("Body is streamable")
347+
log_string += "/nBody is streamable."
343348
else:
344-
_LOGGER.debug(http_response.text())
349+
log_string += "/n{}".format(http_response.text())
350+
_LOGGER.debug(log_string)
345351
except Exception as err: # pylint: disable=broad-except
346352
_LOGGER.debug("Failed to log response: %s", repr(err))
347353

@@ -376,6 +382,7 @@ class HttpLoggingPolicy(SansIOHTTPPolicy):
376382
"User-Agent",
377383
])
378384
REDACTED_PLACEHOLDER = "REDACTED"
385+
MULTI_RECORD_LOG = "AZURE_SDK_LOGGING_MULTIRECORD"
379386

380387
def __init__(self, logger=None, **kwargs): # pylint: disable=unused-argument
381388
self.logger = logger or logging.getLogger(
@@ -396,7 +403,7 @@ def _redact_header(self, key, value):
396403
]
397404
return value if key.lower() in lower_case_allowed_header_names else HttpLoggingPolicy.REDACTED_PLACEHOLDER
398405

399-
def on_request(self, request):
406+
def on_request(self, request): # pylint: disable=too-many-return-statements
400407
# type: (PipelineRequest) -> None
401408
"""Logs HTTP method, url and headers.
402409
:param request: The PipelineRequest object.
@@ -420,26 +427,52 @@ def on_request(self, request):
420427
parsed_url[4] = "&".join(["=".join(part) for part in filtered_qp])
421428
redacted_url = urllib.parse.urlunparse(parsed_url)
422429

423-
logger.info("Request URL: %r", redacted_url)
424-
logger.info("Request method: %r", http_request.method)
425-
logger.info("Request headers:")
430+
multi_record = os.environ.get(HttpLoggingPolicy.MULTI_RECORD_LOG, False)
431+
if multi_record:
432+
logger.info("Request URL: %r", redacted_url)
433+
logger.info("Request method: %r", http_request.method)
434+
logger.info("Request headers:")
435+
for header, value in http_request.headers.items():
436+
value = self._redact_header(header, value)
437+
logger.info(" %r: %r", header, value)
438+
if isinstance(http_request.body, types.GeneratorType):
439+
logger.info("File upload")
440+
return
441+
try:
442+
if isinstance(http_request.body, types.AsyncGeneratorType):
443+
logger.info("File upload")
444+
return
445+
except AttributeError:
446+
pass
447+
if http_request.body:
448+
logger.info("A body is sent with the request")
449+
return
450+
logger.info("No body was attached to the request")
451+
return
452+
log_string = "Request URL: '{}'".format(redacted_url)
453+
log_string += "/nRequest method: '{}'".format(http_request.method)
454+
log_string += "/nRequest headers:"
426455
for header, value in http_request.headers.items():
427456
value = self._redact_header(header, value)
428-
logger.info(" %r: %r", header, value)
457+
log_string += "/n '{}': '{}'".format(header, value)
429458
if isinstance(http_request.body, types.GeneratorType):
430-
logger.info("File upload")
459+
log_string += "/nFile upload"
460+
logger.info(log_string)
431461
return
432462
try:
433463
if isinstance(http_request.body, types.AsyncGeneratorType):
434-
logger.info("File upload")
464+
log_string += "/nFile upload"
465+
logger.info(log_string)
435466
return
436467
except AttributeError:
437468
pass
438469
if http_request.body:
439-
logger.info("A body is sent with the request")
470+
log_string += "/nA body is sent with the request"
471+
logger.info(log_string)
440472
return
441-
logger.info("No body was attached to the request")
442-
return
473+
log_string += "/nNo body was attached to the request"
474+
logger.info(log_string)
475+
443476
except Exception as err: # pylint: disable=broad-except
444477
logger.warning("Failed to log request: %s", repr(err))
445478

@@ -453,15 +486,23 @@ def on_response(self, request, response):
453486
if not logger.isEnabledFor(logging.INFO):
454487
return
455488

456-
logger.info("Response status: %r", http_response.status_code)
457-
logger.info("Response headers:")
489+
multi_record = os.environ.get(HttpLoggingPolicy.MULTI_RECORD_LOG, False)
490+
if multi_record:
491+
logger.info("Response status: %r", http_response.status_code)
492+
logger.info("Response headers:")
493+
for res_header, value in http_response.headers.items():
494+
value = self._redact_header(res_header, value)
495+
logger.info(" %r: %r", res_header, value)
496+
return
497+
log_string = "Response status: {}".format(http_response.status_code)
498+
log_string += "/nResponse headers:"
458499
for res_header, value in http_response.headers.items():
459500
value = self._redact_header(res_header, value)
460-
logger.info(" %r: %r", res_header, value)
501+
log_string += "/n '{}': '{}'".format(res_header, value)
502+
logger.info(log_string)
461503
except Exception as err: # pylint: disable=broad-except
462504
logger.warning("Failed to log response: %s", repr(err))
463505

464-
465506
class ContentDecodePolicy(SansIOHTTPPolicy):
466507
"""Policy for decoding unstreamed response content.
467508

0 commit comments

Comments
 (0)