@@ -321,7 +321,24 @@ def detect(self) -> "Resource":
321321
322322
323323class ProcessResourceDetector (ResourceDetector ):
324- # pylint: disable=no-self-use
324+ """Detect process resource attributes.
325+
326+ Args:
327+ raise_on_error: Raise errors from detection instead of logging them.
328+ include_command_args: Include ``process.command_args`` and
329+ ``process.command_line``. These attributes can contain sensitive
330+ command-line values, so they are excluded by default.
331+ """
332+
333+ def __init__ (
334+ self ,
335+ raise_on_error : bool = False ,
336+ * ,
337+ include_command_args : bool = False ,
338+ ) -> None :
339+ super ().__init__ (raise_on_error = raise_on_error )
340+ self ._include_command_args = include_command_args
341+
325342 def detect (self ) -> "Resource" :
326343 _runtime_version = "." .join (
327344 map (
@@ -337,27 +354,24 @@ def detect(self) -> "Resource":
337354 _process_pid = os .getpid ()
338355 _process_executable_name = sys .executable
339356 _process_executable_path = os .path .dirname (_process_executable_name )
340- # Use sys.orig_argv, which preserves the original arguments received
341- # by the interpreter. This correctly captures ``python -m <module>``
342- # invocations where sys.argv is rewritten to the resolved module path
343- # and the ``-m <module>`` information is lost. sys.orig_argv also
344- # aligns with /proc/<pid>/cmdline, which the OTel semantic
345- # conventions reference for these attributes.
346- _process_argv = list (sys .orig_argv )
347- _process_command = _process_argv [0 ] if _process_argv else ""
348- _process_command_line = " " .join (_process_argv )
349- _process_command_args = _process_argv
350- resource_info = {
357+ # Use sys.orig_argv, which has the original arguments received
358+ # by the interpreter. The spec says full command arguments are opt-in
359+ # and they can contain sensitive data.
360+ _process_command = sys .orig_argv [0 ] if sys .orig_argv else ""
361+ resource_info : dict [str , AttributeValue ] = {
351362 PROCESS_RUNTIME_DESCRIPTION : sys .version ,
352363 PROCESS_RUNTIME_NAME : sys .implementation .name ,
353364 PROCESS_RUNTIME_VERSION : _runtime_version ,
354365 PROCESS_PID : _process_pid ,
355366 PROCESS_EXECUTABLE_NAME : _process_executable_name ,
356367 PROCESS_EXECUTABLE_PATH : _process_executable_path ,
357368 PROCESS_COMMAND : _process_command ,
358- PROCESS_COMMAND_LINE : _process_command_line ,
359- PROCESS_COMMAND_ARGS : _process_command_args ,
360369 }
370+ if self ._include_command_args :
371+ _process_argv = list (sys .orig_argv )
372+ resource_info [PROCESS_COMMAND_LINE ] = " " .join (_process_argv )
373+ resource_info [PROCESS_COMMAND_ARGS ] = _process_argv
374+
361375 if hasattr (os , "getppid" ):
362376 # pypy3 does not have getppid()
363377 resource_info [PROCESS_PARENT_PID ] = os .getppid ()
0 commit comments