There is no easy automatic way to process all the exception, it contradict with exception handling idea.
One of solutions: we can log all uncatched exceptions like this way:
import sys
import logging
logger = logging.getLogger(__name__)
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)
def handle_exception(exc_type, exc_value, exc_traceback):
    if issubclass(exc_type, KeyboardInterrupt):
        sys.__excepthook__(exc_type, exc_value, exc_traceback)
    else:
        logger.critical("Exception occured:", exc_info=(exc_type, exc_value, exc_traceback))
sys.excepthook = handle_exception
# Just to test
if __name__ == "__main__":
    raise Exception("Something happend!")
And to log all handled exception we need to all logging in except block:
try:
    ...
except:
    logger.error("Exception occured:", exc_info=(exc_type, exc_value, exc_traceback))
    ...
Other way to deal with exception is to handle them in top-level function. All non-handled exceptions from downstream functions will be processed in top-level except block:
def my_main_func():
    try:
        run_my_application_logic()
    except:
        # Logging
        logger.error("Exception occured:", exc_info=(exc_type, exc_value, exc_traceback))
def run_my_application_logic():
    first_step_of_app()
    second_step_of_app()
    third_step_of_app()
if __name__ == "__main__":
    my_main_func()