Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add process.name attribute and adapt process.executable.name #1737

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .chloggen/process_name.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Use this changelog template to create an entry for release notes.
#
# If your change doesn't affect end users you should instead start
# your pull request title with [chore] or use the "Skip Changelog" label.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the area of concern in the attributes-registry, (e.g. http, cloud, db)
component: process

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Added new attribute `process.name`, adjusted guidance for `process.executable.name`

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
# The values here must be integers.
issues: [1736]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
The new `process.name` attribute uses the original guidance for `process.executable.name`,
suggesting use of `/proc/[pid]/comm` or the `Name` field from `/proc/[pid]/status` on Linux.
`process.executable.name` guidance now suggests using the base name from the `/proc/[pid]/exe`
symlink's target path.
3 changes: 2 additions & 1 deletion docs/attributes-registry/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,13 @@ An operating system process.
| <a id="process-executable-build-id-gnu" href="#process-executable-build-id-gnu">`process.executable.build_id.gnu`</a> | string | The GNU build ID as found in the `.note.gnu.build-id` ELF section (hex string). | `c89b11207f6479603b0d49bf291c092c2b719293` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-executable-build-id-go" href="#process-executable-build-id-go">`process.executable.build_id.go`</a> | string | The Go build ID as retrieved by `go tool buildid <go executable>`. | `foh3mEXu7BLZjsN9pOwG/kATcXlYVCDEFouRMQed_/WwRFB1hPo9LBkekthSPG/x8hMC8emW2cCjXD0_1aY` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-executable-build-id-htlhash" href="#process-executable-build-id-htlhash">`process.executable.build_id.htlhash`</a> | string | Profiling specific build ID for executables. See the OTel specification for Profiles for more information. | `600DCAFE4A110000F2BF38C493F5FB92` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-executable-name" href="#process-executable-name">`process.executable.name`</a> | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-executable-name" href="#process-executable-name">`process.executable.name`</a> | string | The name of the process executable. On Linux based systems, can be set to the base name of the target of `/proc/[pid]/exe`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-executable-path" href="#process-executable-path">`process.executable.path`</a> | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-exit-code" href="#process-exit-code">`process.exit.code`</a> | int | The exit code of the process. | `127` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-exit-time" href="#process-exit-time">`process.exit.time`</a> | string | The date and time the process exited, in ISO 8601 format. | `2023-11-21T09:26:12.315Z` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-group-leader-pid" href="#process-group-leader-pid">`process.group_leader.pid`</a> | int | The PID of the process's group leader. This is also the process group ID (PGID) of the process. | `23` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-interactive" href="#process-interactive">`process.interactive`</a> | boolean | Whether the process is connected to an interactive shell. | | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-name" href="#process-name">`process.name`</a> | string | The name of the process. On Linux based systems, can be set to the value of `/proc/[pid]/comm` or to the `Name` field in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-owner" href="#process-owner">`process.owner`</a> | string | The username of the user that owns the process. | `root` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-paging-fault-type" href="#process-paging-fault-type">`process.paging.fault_type`</a> | string | The type of page fault for this data point. Type `major` is for major/hard page faults, and `minor` is for minor/soft page faults. | `major`; `minor` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| <a id="process-parent-pid" href="#process-parent-pid">`process.parent_pid`</a> | int | Parent Process identifier (PPID). | `111` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
Expand Down
4 changes: 2 additions & 2 deletions docs/cli/cli-spans.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Span status SHOULD be set to `Error` if `{process.exit.code}` is not 0.

| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
| [`process.executable.name`](/docs/attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.executable.name`](/docs/attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the base name of the target of `/proc/[pid]/exe`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.exit.code`](/docs/attributes-registry/process.md) | int | The exit code of the process. | `127` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.pid`](/docs/attributes-registry/process.md) | int | Process identifier (PID). | `1234` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if and only if process.exit.code is not 0 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
Expand Down Expand Up @@ -79,7 +79,7 @@ it's RECOMMENDED to:

| Attribute | Type | Description | Examples | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Stability |
|---|---|---|---|---|---|
| [`process.executable.name`](/docs/attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.executable.name`](/docs/attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the base name of the target of `/proc/[pid]/exe`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.exit.code`](/docs/attributes-registry/process.md) | int | The exit code of the process. | `127` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.pid`](/docs/attributes-registry/process.md) | int | Process identifier (PID). | `1234` | `Required` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`error.type`](/docs/attributes-registry/error.md) | string | Describes a class of error the operation ended with. [1] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` | `Conditionally Required` if and only if process.exit.code is not 0 | ![Stable](https://img.shields.io/badge/-stable-lightgreen) |
Expand Down
2 changes: 1 addition & 1 deletion docs/resource/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
| [`process.command`](/docs/attributes-registry/process.md) | string | The command used to launch the process (i.e. the command name). On Linux based systems, can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to the first parameter extracted from `GetCommandLineW`. | `cmd/otelcol` | `Conditionally Required` [1] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.command_args`](/docs/attributes-registry/process.md) | string[] | All the command arguments (including the command/executable itself) as received by the process. On Linux-based systems (and some other Unixoid systems supporting procfs), can be set according to the list of null-delimited strings extracted from `proc/[pid]/cmdline`. For libc-based executables, this would be the full argv vector passed to `main`. | `["cmd/otecol", "--config=config.yaml"]` | `Conditionally Required` [2] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.command_line`](/docs/attributes-registry/process.md) | string | The full command used to launch the process as a single string representing the full command. On Windows, can be set to the result of `GetCommandLineW`. Do not set this if you have to assemble it just for monitoring; use `process.command_args` instead. | `C:\cmd\otecol --config="my directory\config.yaml"` | `Conditionally Required` [3] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.executable.name`](/docs/attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the `Name` in `proc/[pid]/status`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.executable.name`](/docs/attributes-registry/process.md) | string | The name of the process executable. On Linux based systems, can be set to the base name of the target of `/proc/[pid]/exe`. On Windows, can be set to the base name of `GetProcessImageFileNameW`. | `otelcol` | `Conditionally Required` [4] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.executable.path`](/docs/attributes-registry/process.md) | string | The full path to the process executable. On Linux based systems, can be set to the target of `proc/[pid]/exe`. On Windows, can be set to the result of `GetProcessImageFileNameW`. | `/usr/bin/cmd/otelcol` | `Conditionally Required` [5] | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.linux.cgroup`](/docs/attributes-registry/process.md) | string | The control group associated with the process. [6] | `1:name=systemd:/user.slice/user-1000.slice/session-3.scope`; `0::/user.slice/user-1000.slice/[email protected]/tmux-spawn-0267755b-4639-4a27-90ed-f19f88e53748.scope` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
| [`process.owner`](/docs/attributes-registry/process.md) | string | The username of the user that owns the process. | `root` | `Recommended` | ![Experimental](https://img.shields.io/badge/-experimental-blue) |
Expand Down
12 changes: 10 additions & 2 deletions model/process/registry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ groups:
brief: >
Process identifier (PID).
examples: [1234]
- id: process.name
type: string
stability: experimental
brief: >
The name of the process. On Linux based systems, can be set to
lmolkova marked this conversation as resolved.
Show resolved Hide resolved
the value of `/proc/[pid]/comm` or to the `Name` field in `proc/[pid]/status`.
On Windows, can be set to the base name of `GetProcessImageFileNameW`.
examples: ['otelcol']
- id: process.parent_pid
type: int
stability: experimental
Expand Down Expand Up @@ -65,8 +73,8 @@ groups:
stability: experimental
brief: >
The name of the process executable. On Linux based systems, can be set
to the `Name` in `proc/[pid]/status`. On Windows, can be set to the
base name of `GetProcessImageFileNameW`.
to the base name of the target of `/proc/[pid]/exe`. On Windows,
can be set to the base name of `GetProcessImageFileNameW`.
Copy link
Contributor

@lmolkova lmolkova Jan 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems process.name and process.executable.name are always the same on windows - is it the case?

In the spirit of T-shaped API, do you think it could be one of these linux-specific things? I.e. process.linux.exe|exectuable.name ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this specification, it is the case that process.name and process.executable.name will be the same on Windows. I dug as far as I could into Win32 and .NET APIs to see if there was ever a way to change a process's name at runtime like in Linux, and I could not find any way to do so. So I think it is fundamentally the case even outside of this specification that process name and executable name will always be the same on Windows.

I think there is a good use-case for maintaining process.executable.name as a cross-platform name, and that's how it's used in CLI. In this case, it seems the way it's used is for the attribute to be the executable name on both Linux and Windows. On Linux this distinction matters, whereas on Windows it doesn't. However, this ensures that on either platform the cli.internal span will always have a correct executable name, and doesn't need to worry about special attributes based on the platform.

Perhaps I could add a note in process.executable.name's description that on Windows it will always be the same, and can be excluded if you're already using process.name?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can generalize this a bit to be OS-agnostic?

  • OTEL is not only about Linux and Windows
  • missing features in Windows or other OSes may appear with the next version/upgrade

So, can we just say that the two fields may have the same value?
That is often true on Linux and always true for current Windows versions and below.

It still makes sense for Windows clients to send both fields, otherwise there should be a written hint/rule like "if process.name isn't set, fallback to process.executable.name" or the other way round.

Copy link
Contributor

@lmolkova lmolkova Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use process.executable.name in CLI conventions because it was the only one that existed.

The question I feel we should address:

If I have some instrumentation that would benefit from having a process name, but does not need a lot of details ("General Class") - which one of those attributes I should use? I'm going to say process.name is the first candidate just because it's shorter and looks very general.

In this sense, I would even suggest to change process.name definition to be the best known name (yes, you can get it using OS APIs, but maybe you have a smart way to generate better process names, or maybe you want to record friendly process name when self-reporting it from within a process).

Let me try to phrase it (will leave a separate comment with suggestion)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

examples: ['otelcol']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be possible to have an example that's different between process.name and process.executable.name ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where would be the best place for that? As part of this description?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added it as a note on process.name in cd4c335

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant if we could have realistic example that's different on linux in examples: ['otelcol'], it's minor.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it be possible to have an example that's different between process.name and process.executable.name ?

For Linux, one example where the process name isn't changed programmatically is using a symbolic link, for example ln -s foo bar. Running ./bar gives you bar from /proc/<PID>/comm, but the basename foo from readlink /proc/<PID>/exe.

A real example for this is unlz4 which is a link to the lz4 executable (on my Debian system). So as you say in your suggestion, process.name seems to be more relevant/precise here.

Unfortunate, there are other examples where process.name needs to be combined with process.executable.path:

UnicodeNameMappingGenerator-16 -> ../lib/llvm-16/bin/UnicodeNameMappingGenerator
UnicodeNameMappingGenerator-17 -> ../lib/llvm-17/bin/UnicodeNameMappingGenerator

process.name: UnicodeNameMap (in both cases)
process.executable.name: UnicodeNameMappingGenerator (in both cases)

- id: process.executable.path
type: string
Expand Down
Loading