Skip to content

Formatter.format's exc_text cache breaks multiple formatters formatting a message in different ways #137790

@dcolascione

Description

@dcolascione

Bug report

Bug description:

logging.Formatter.format caches the result of formatting an log record's exception in the log record itself. When multiple handlers handle an exception, only the first's exception formatting is actually used. This behavior breaks the ability to format exceptions different ways for different logging destinations, e.g. with colors for TTY output and plainly for log file output.

In the program below, formatException is called only one even though we have two logging handlers and two formatter objects.

#!/usr/bin/env python3
import os
import sys
import logging

class MyFormatter(logging.Formatter):
    def formatException(self, ei):
        print("formatException called")
        return super().formatException(ei)

h1 = logging.StreamHandler()
h1.setFormatter(MyFormatter())
logging.getLogger().addHandler(h1)

h2 = logging.StreamHandler()
h2.setFormatter(MyFormatter())
logging.getLogger().addHandler(h2)

logging.error("XXX", exc_info=Exception())

Expected output:

formatException called
XXX
Exception
formatException called
XXX
Exception

Actual output:

formatException called
XXX
Exception
XXX
Exception

CPython versions tested on:

3.11

Operating systems tested on:

macOS

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibPython modules in the Lib dirtype-bugAn unexpected behavior, bug, or error

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions