diff --git a/azure_functions_worker/dispatcher.py b/azure_functions_worker/dispatcher.py index cf177f930..7ec9feb74 100644 --- a/azure_functions_worker/dispatcher.py +++ b/azure_functions_worker/dispatcher.py @@ -34,7 +34,7 @@ from .logging import disable_console_logging, enable_console_logging from .logging import enable_debug_logging_recommendation from .logging import (logger, error_logger, is_system_log_category, - CONSOLE_LOG_PREFIX) + CONSOLE_LOG_PREFIX, format_exception) from .utils.common import get_app_setting, is_envvar_true from .utils.dependency import DependencyManager from .utils.tracing import marshall_exception_trace @@ -696,7 +696,9 @@ def gen(resp_queue): if ex is grpc_req_stream: # Yes, this is how grpc_req_stream iterator exits. return - error_logger.exception('unhandled error in gRPC thread') + error_logger.exception( + 'unhandled error in gRPC thread. Exception: {0}'.format( + format_exception(ex))) raise diff --git a/azure_functions_worker/logging.py b/azure_functions_worker/logging.py index 4f8fac2ea..d8ec5cbec 100644 --- a/azure_functions_worker/logging.py +++ b/azure_functions_worker/logging.py @@ -4,6 +4,7 @@ from typing import Optional import logging import logging.handlers +import traceback import sys # Logging Prefixes @@ -20,6 +21,13 @@ error_handler: Optional[logging.Handler] = None +def format_exception(exception): + msg = str(exception) + "\n" + msg += ''.join(traceback.format_exception( + etype=type(exception), value=exception, tb=exception.__traceback__)) + return msg + + def setup(log_level, log_destination): # Since handler and error_handler are moved to the global scope, # before assigning to these handlers, we should define 'global' keyword diff --git a/azure_functions_worker/main.py b/azure_functions_worker/main.py index 3a7e44417..c1b0f293e 100644 --- a/azure_functions_worker/main.py +++ b/azure_functions_worker/main.py @@ -36,20 +36,21 @@ def main(): from . import logging from ._thirdparty import aio_compat - from .logging import error_logger, logger + from .logging import error_logger, logger, format_exception args = parse_args() logging.setup(log_level=args.log_level, log_destination=args.log_to) - - logger.info('Starting Azure Functions Python Worker.') - logger.info('Worker ID: %s, Request ID: %s, Host Address: %s:%s', + logger.info('Starting Azure Functions Python Worker. \n' + 'Worker ID: %s, Request ID: %s, Host Address: %s:%s', args.worker_id, args.request_id, args.host, args.port) try: return aio_compat.run(start_async( args.host, args.port, args.worker_id, args.request_id)) - except Exception: - error_logger.exception('unhandled error in functions worker') + except Exception as ex: + error_logger.exception( + 'unhandled error in functions worker: {0}'.format( + format_exception(ex))) raise diff --git a/setup.py b/setup.py index 684225ab0..56c7509dd 100644 --- a/setup.py +++ b/setup.py @@ -112,7 +112,7 @@ "grpcio~=1.43.0", "grpcio-tools~=1.43.0", "protobuf~=3.19.3", - "azure-functions==1.10.1" + "azure-functions==1.11.3b2" ]