From 5361ced5a26552f4ff737bea19662100868ed1f7 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Sun, 8 Mar 2026 20:37:16 -0700 Subject: [PATCH] gh-145238: Add native thread ID to logging record attributes Add a `nativeThreadId` attribute to `LogRecord` that exposes the OS-native thread ID via `threading.get_native_id()`. This is useful for correlating log entries with system tools like htop, strace, and perf that display native thread IDs. The attribute can be used in format strings as `%(nativeThreadId)d`. Co-Authored-By: Claude Opus 4.6 --- Doc/library/logging.rst | 6 ++++++ Lib/logging/__init__.py | 5 +++++ .../Library/2026-03-08-00-00-00.gh-issue-145238.nThrId.rst | 3 +++ 3 files changed, 14 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-03-08-00-00-00.gh-issue-145238.nThrId.rst diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index aba530844d7177..136fbd7edf6862 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -1062,6 +1062,9 @@ the options available to you. | | | of the logging call which resulted in the | | | | creation of this record. | +----------------+-------------------------+-----------------------------------------------+ +| nativeThreadId | ``%(nativeThreadId)d`` | Native thread ID (if available). See | +| | | :func:`threading.get_native_id`. | ++----------------+-------------------------+-----------------------------------------------+ | thread | ``%(thread)d`` | Thread ID (if available). | +----------------+-------------------------+-----------------------------------------------+ | threadName | ``%(threadName)s`` | Thread name (if available). | @@ -1075,6 +1078,9 @@ the options available to you. .. versionchanged:: 3.12 *taskName* was added. +.. versionchanged:: 3.15 + *nativeThreadId* was added. + .. _logger-adapter: LoggerAdapter Objects diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 39689a57e6ecd6..9f5b5a48b22d26 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -350,9 +350,14 @@ def __init__(self, name, level, pathname, lineno, if logThreads: self.thread = threading.get_ident() self.threadName = threading.current_thread().name + if threading._HAVE_THREAD_NATIVE_ID: + self.nativeThreadId = threading.get_native_id() + else: # pragma: no cover + self.nativeThreadId = None else: # pragma: no cover self.thread = None self.threadName = None + self.nativeThreadId = None if not logMultiprocessing: # pragma: no cover self.processName = None else: diff --git a/Misc/NEWS.d/next/Library/2026-03-08-00-00-00.gh-issue-145238.nThrId.rst b/Misc/NEWS.d/next/Library/2026-03-08-00-00-00.gh-issue-145238.nThrId.rst new file mode 100644 index 00000000000000..1a712696aebb33 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-03-08-00-00-00.gh-issue-145238.nThrId.rst @@ -0,0 +1,3 @@ +Added ``nativeThreadId`` attribute to :class:`logging.LogRecord`, exposing +the OS-native thread ID via :func:`threading.get_native_id`. This can be +used in format strings as ``%(nativeThreadId)d``.