diff --git a/.chloggen/define-vcs-span-conventions.yaml b/.chloggen/define-vcs-span-conventions.yaml
new file mode 100644
index 0000000000..663eb1c6aa
--- /dev/null
+++ b/.chloggen/define-vcs-span-conventions.yaml
@@ -0,0 +1,4 @@
+change_type: enhancement
+component: vcs
+note: "Define span conventions for Version Control System (VCS) operations and introduce the `vcs.operation.name` attribute."
+issues: [3767]
diff --git a/docs/cicd/cicd-spans.md b/docs/cicd/cicd-spans.md
index 5e414efd3d..7906393659 100644
--- a/docs/cicd/cicd-spans.md
+++ b/docs/cicd/cicd-spans.md
@@ -4,13 +4,14 @@ linkTitle: Spans
# Semantic conventions for CI/CD spans
-**Status**: [Release Candidate][DocumentStatus]
+**Status**: [Mixed][DocumentStatus]
- [CI/CD Spans](#cicd-spans)
- [Pipeline run](#pipeline-run)
- [Pipeline task run](#pipeline-task-run)
+- [VCS client span](#vcs-client-span)
@@ -202,4 +203,118 @@ and SHOULD be provided **at span creation time** (if provided at all):
+## VCS client span
+
+
+
+
+
+
+**Status:** 
+
+This span describes a Version Control System (VCS) operation client, such as a Git CLI command or a CI/CD pipeline step cloning a repository.
+
+VCS client spans are typically emitted by CI/CD pipeline steps executing VCS operations (e.g. checkout or clone tasks),
+or by wrapper tools and CLI utilities performing Git, SVN, or Mercurial operations.
+
+**Span name** MUST follow the overall [guidelines for span names](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#span).
+
+The span name SHOULD follow the `{vcs.operation.name} {vcs.repository.name}` pattern,
+or `{vcs.operation.name}` if target information is not applicable or available.
+If the operation target is more specific (e.g. a branch or ref), the span name MAY be `{vcs.operation.name} {vcs.ref.head.name}`
+or `{vcs.operation.name} {vcs.repository.name} {vcs.ref.head.name}`.
+
+**Span kind** SHOULD be `CLIENT`.
+
+**Span status** SHOULD follow the [Recording Errors](/docs/general/recording-errors.md) document.
+
+**Attributes:**
+
+| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- | --- |
+| [`vcs.operation.name`](/docs/registry/attributes/vcs.md) |  | `Required` | string | The type of action or operation performed by a VCS. [1] | `clone`; `fetch`; `pull`; `push`; `checkout`; `sync` |
+| [`vcs.repository.name`](/docs/registry/attributes/vcs.md) |  | `Required` | string | The human readable name of the repository. It SHOULD NOT include any additional identifier like Group/SubGroup in GitLab or organization in GitHub. [2] | `semantic-conventions`; `my-cool-repo` |
+| [`error.type`](/docs/registry/attributes/error.md) |  | `Conditionally Required` If the VCS operation fails. | string | Describes a class of error the operation ended with. [3] | `timeout`; `java.net.UnknownHostException`; `server_certificate_invalid`; `500` |
+| [`server.address`](/docs/registry/attributes/server.md) |  | `Recommended` | string | The remote VCS server address (e.g. github.com, gitlab.com, or self-hosted Git server). [4] | `example.com`; `10.1.2.80`; `/tmp/my.sock` |
+| [`server.port`](/docs/registry/attributes/server.md) |  | `Recommended` | int | Server port number. [5] | `80`; `8080`; `443` |
+| [`vcs.ref.head.name`](/docs/registry/attributes/vcs.md) |  | `Recommended` | string | The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. [6] | `my-feature-branch`; `tag-1-test` |
+| [`vcs.ref.head.revision`](/docs/registry/attributes/vcs.md) |  | `Recommended` | string | The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. [7] | `9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc`; `main`; `123`; `HEAD` |
+| [`vcs.ref.type`](/docs/registry/attributes/vcs.md) |  | `Recommended` | string | The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. | `branch`; `tag` |
+| [`vcs.repository.url.full`](/docs/registry/attributes/vcs.md) |  | `Recommended` | string | The [canonical URL](https://support.google.com/webmasters/answer/10347851) of the repository providing the complete HTTP(S) address in order to locate and identify the repository through a browser. [8] | `https://github.com/opentelemetry/open-telemetry-collector-contrib`; `https://gitlab.com/my-org/my-project/my-projects-project/repo` |
+
+**[1] `vcs.operation.name`:** For example, in Git, operations include `clone`, `fetch`, `pull`, `push`, `checkout`, etc. In other VCS systems like Perforce or SVN, the operation names may be different (e.g. `sync`, `update`). It SHOULD be the exact operation name as executed by the tool.
+
+**[2] `vcs.repository.name`:** Due to it only being the name, it can clash with forks of the same
+repository if collecting telemetry across multiple orgs or groups in
+the same backends.
+
+**[3] `error.type`:** The `error.type` SHOULD be predictable, and SHOULD have low cardinality.
+
+When `error.type` is set to a type (e.g., an exception type), its
+canonical class name identifying the type within the artifact SHOULD be used.
+
+If the recorded error type is a wrapper that is not meaningful for
+failure classification, instrumentation MAY use the type of the inner
+error instead. For example, in Go, errors created with `fmt.Errorf`
+using `%w` MAY be unwrapped when the wrapper type does not help
+classify the failure.
+
+Instrumentations SHOULD document the list of errors they report.
+
+The cardinality of `error.type` within one instrumentation library SHOULD be low.
+Telemetry consumers that aggregate data from multiple instrumentation libraries and applications
+should be prepared for `error.type` to have high cardinality at query time when no
+additional filters are applied.
+
+If the operation has completed successfully, instrumentations SHOULD NOT set `error.type`.
+
+If a specific domain defines its own set of error identifiers (such as HTTP or RPC status codes),
+it's RECOMMENDED to:
+
+- Use a domain-specific attribute
+- Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not.
+
+**[4] `server.address`:** When observed from the client side, and when communicating through an intermediary, `server.address` SHOULD represent the server address behind any intermediaries, for example proxies, if it's available.
+
+**[5] `server.port`:** When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent the server port behind any intermediaries, for example proxies, if it's available.
+
+**[6] `vcs.ref.head.name`:** `head` refers to where you are right now; the current reference at a
+given time.
+
+**[7] `vcs.ref.head.revision`:** `head` refers to where you are right now; the current reference at a
+given time.The revision can be a full [hash value (see
+glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf),
+of the recorded change to a ref within a repository pointing to a
+commit [commit](https://git-scm.com/docs/git-commit) object. It does
+not necessarily have to be a hash; it can simply define a [revision
+number](https://svnbook.red-bean.com/en/1.7/svn.tour.revs.specifiers.html)
+which is an integer that is monotonically increasing. In cases where
+it is identical to the `ref.head.name`, it SHOULD still be included.
+It is up to the implementer to decide which value to set as the
+revision based on the VCS system and situational context.
+
+**[8] `vcs.repository.url.full`:** In Git Version Control Systems, the canonical URL SHOULD NOT include
+the `.git` extension.
+
+---
+
+`error.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
+
+| Value | Description | Stability |
+| --- | --- | --- |
+| `_OTHER` | A fallback error value to be used when the instrumentation doesn't define a custom value. |  |
+
+---
+
+`vcs.ref.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
+
+| Value | Description | Stability |
+| --- | --- | --- |
+| `branch` | [branch](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefbranchabranch) |  |
+| `tag` | [tag](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddeftagatag) |  |
+
+
+
+
+
[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status
diff --git a/docs/http/http-spans.md b/docs/http/http-spans.md
index 51fdcdb1ef..c9d1a38c39 100644
--- a/docs/http/http-spans.md
+++ b/docs/http/http-spans.md
@@ -278,6 +278,7 @@ If the request has completed successfully, instrumentations SHOULD NOT set `erro
Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.
The `User-Agent` header is already captured in the `user_agent.original` attribute.
+
Users MAY explicitly configure instrumentations to capture them even though it is not recommended.
The attribute value MUST consist of either multiple header values as an array of strings
@@ -596,6 +597,7 @@ When a query string value is redacted, the query string key SHOULD still be pres
Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.
The `User-Agent` header is already captured in the `user_agent.original` attribute.
+
Users MAY explicitly configure instrumentations to capture them even though it is not recommended.
The attribute value MUST consist of either multiple header values as an array of strings
diff --git a/docs/registry/attributes/http.md b/docs/registry/attributes/http.md
index 5f48f1d314..c06ffd0d20 100644
--- a/docs/registry/attributes/http.md
+++ b/docs/registry/attributes/http.md
@@ -31,6 +31,7 @@ This document defines semantic convention attributes in the HTTP namespace.
Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.
The `User-Agent` header is already captured in the `user_agent.original` attribute.
+
Users MAY explicitly configure instrumentations to capture them even though it is not recommended.
The attribute value MUST consist of either multiple header values as an array of strings
diff --git a/docs/registry/attributes/vcs.md b/docs/registry/attributes/vcs.md
index 3be6d23b15..c02eb30cb5 100644
--- a/docs/registry/attributes/vcs.md
+++ b/docs/registry/attributes/vcs.md
@@ -18,24 +18,27 @@ This group defines the attributes for [Version Control Systems (VCS)](https://wi
| `vcs.change.state` |  | string | The state of the change (pull request/merge request/changelist). | `open`; `closed`; `merged` |
| `vcs.change.title` |  | string | The human readable title of the change (pull request/merge request/changelist). This title is often a brief summary of the change and may get merged in to a ref as the commit summary. | `Fixes broken thing`; `feat: add my new feature`; `[chore] update dependency` |
| `vcs.line_change.type` |  | string | The type of line change being measured on a branch or change. | `added`; `removed` |
+| `vcs.operation.name` |  | string | The type of action or operation performed by a VCS. [1] | `clone`; `fetch`; `pull`; `push`; `checkout`; `sync` |
| `vcs.owner.name` |  | string | The group owner within the version control system. | `my-org`; `myteam`; `business-unit` |
| `vcs.provider.name` |  | string | The name of the version control system provider. | `github`; `gitlab`; `gitea`; `bitbucket` |
-| `vcs.ref.base.name` |  | string | The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. [1] | `my-feature-branch`; `tag-1-test` |
-| `vcs.ref.base.revision` |  | string | The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. [2] | `9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc`; `main`; `123`; `HEAD` |
-| `vcs.ref.base.type` |  | string | The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. [3] | `branch`; `tag` |
-| `vcs.ref.head.name` |  | string | The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. [4] | `my-feature-branch`; `tag-1-test` |
-| `vcs.ref.head.revision` |  | string | The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. [5] | `9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc`; `main`; `123`; `HEAD` |
-| `vcs.ref.head.type` |  | string | The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. [6] | `branch`; `tag` |
+| `vcs.ref.base.name` |  | string | The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. [2] | `my-feature-branch`; `tag-1-test` |
+| `vcs.ref.base.revision` |  | string | The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. [3] | `9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc`; `main`; `123`; `HEAD` |
+| `vcs.ref.base.type` |  | string | The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. [4] | `branch`; `tag` |
+| `vcs.ref.head.name` |  | string | The name of the [reference](https://git-scm.com/docs/gitglossary#def_ref) such as **branch** or **tag** in the repository. [5] | `my-feature-branch`; `tag-1-test` |
+| `vcs.ref.head.revision` |  | string | The revision, literally [revised version](https://www.merriam-webster.com/dictionary/revision), The revision most often refers to a commit object in Git, or a revision number in SVN. [6] | `9d59409acf479dfa0df1aa568182e43e43df8bbe28d60fcf2bc52e30068802cc`; `main`; `123`; `HEAD` |
+| `vcs.ref.head.type` |  | string | The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. [7] | `branch`; `tag` |
| `vcs.ref.type` |  | string | The type of the [reference](https://git-scm.com/docs/gitglossary#def_ref) in the repository. | `branch`; `tag` |
-| `vcs.repository.name` |  | string | The human readable name of the repository. It SHOULD NOT include any additional identifier like Group/SubGroup in GitLab or organization in GitHub. [7] | `semantic-conventions`; `my-cool-repo` |
-| `vcs.repository.url.full` |  | string | The [canonical URL](https://support.google.com/webmasters/answer/10347851) of the repository providing the complete HTTP(S) address in order to locate and identify the repository through a browser. [8] | `https://github.com/opentelemetry/open-telemetry-collector-contrib`; `https://gitlab.com/my-org/my-project/my-projects-project/repo` |
+| `vcs.repository.name` |  | string | The human readable name of the repository. It SHOULD NOT include any additional identifier like Group/SubGroup in GitLab or organization in GitHub. [8] | `semantic-conventions`; `my-cool-repo` |
+| `vcs.repository.url.full` |  | string | The [canonical URL](https://support.google.com/webmasters/answer/10347851) of the repository providing the complete HTTP(S) address in order to locate and identify the repository through a browser. [9] | `https://github.com/opentelemetry/open-telemetry-collector-contrib`; `https://gitlab.com/my-org/my-project/my-projects-project/repo` |
| `vcs.revision_delta.direction` |  | string | The type of revision comparison. | `ahead`; `behind` |
-**[1] `vcs.ref.base.name`:** `base` refers to the starting point of a change. For example, `main`
+**[1] `vcs.operation.name`:** For example, in Git, operations include `clone`, `fetch`, `pull`, `push`, `checkout`, etc. In other VCS systems like Perforce or SVN, the operation names may be different (e.g. `sync`, `update`). It SHOULD be the exact operation name as executed by the tool.
+
+**[2] `vcs.ref.base.name`:** `base` refers to the starting point of a change. For example, `main`
would be the base reference of type branch if you've created a new
reference of type branch from it and created new commits.
-**[2] `vcs.ref.base.revision`:** `base` refers to the starting point of a change. For example, `main`
+**[3] `vcs.ref.base.revision`:** `base` refers to the starting point of a change. For example, `main`
would be the base reference of type branch if you've created a new
reference of type branch from it and created new commits. The
revision can be a full [hash value (see
@@ -49,14 +52,14 @@ it is identical to the `ref.base.name`, it SHOULD still be included.
It is up to the implementer to decide which value to set as the
revision based on the VCS system and situational context.
-**[3] `vcs.ref.base.type`:** `base` refers to the starting point of a change. For example, `main`
+**[4] `vcs.ref.base.type`:** `base` refers to the starting point of a change. For example, `main`
would be the base reference of type branch if you've created a new
reference of type branch from it and created new commits.
-**[4] `vcs.ref.head.name`:** `head` refers to where you are right now; the current reference at a
+**[5] `vcs.ref.head.name`:** `head` refers to where you are right now; the current reference at a
given time.
-**[5] `vcs.ref.head.revision`:** `head` refers to where you are right now; the current reference at a
+**[6] `vcs.ref.head.revision`:** `head` refers to where you are right now; the current reference at a
given time.The revision can be a full [hash value (see
glossary)](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf),
of the recorded change to a ref within a repository pointing to a
@@ -68,14 +71,14 @@ it is identical to the `ref.head.name`, it SHOULD still be included.
It is up to the implementer to decide which value to set as the
revision based on the VCS system and situational context.
-**[6] `vcs.ref.head.type`:** `head` refers to where you are right now; the current reference at a
+**[7] `vcs.ref.head.type`:** `head` refers to where you are right now; the current reference at a
given time.
-**[7] `vcs.repository.name`:** Due to it only being the name, it can clash with forks of the same
+**[8] `vcs.repository.name`:** Due to it only being the name, it can clash with forks of the same
repository if collecting telemetry across multiple orgs or groups in
the same backends.
-**[8] `vcs.repository.url.full`:** In Git Version Control Systems, the canonical URL SHOULD NOT include
+**[9] `vcs.repository.url.full`:** In Git Version Control Systems, the canonical URL SHOULD NOT include
the `.git` extension.
---
diff --git a/model/http/registry.yaml b/model/http/registry.yaml
index d91c2d8762..749e0c4b1d 100644
--- a/model/http/registry.yaml
+++ b/model/http/registry.yaml
@@ -22,6 +22,7 @@ groups:
Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.
The `User-Agent` header is already captured in the `user_agent.original` attribute.
+
Users MAY explicitly configure instrumentations to capture them even though it is not recommended.
The attribute value MUST consist of either multiple header values as an array of strings
diff --git a/model/vcs/registry.yaml b/model/vcs/registry.yaml
index 3725fdd5ec..a402ab8593 100644
--- a/model/vcs/registry.yaml
+++ b/model/vcs/registry.yaml
@@ -285,3 +285,13 @@ groups:
"gitea",
"bitbucket",
]
+ - id: vcs.operation.name
+ type: string
+ stability: development
+ brief: >
+ The type of action or operation performed by a VCS.
+ note: >
+ For example, in Git, operations include `clone`, `fetch`, `pull`, `push`, `checkout`, etc.
+ In other VCS systems like Perforce or SVN, the operation names may be different (e.g. `sync`, `update`).
+ It SHOULD be the exact operation name as executed by the tool.
+ examples: ["clone", "fetch", "pull", "push", "checkout", "sync"]
diff --git a/model/vcs/spans.yaml b/model/vcs/spans.yaml
new file mode 100644
index 0000000000..743d2231f3
--- /dev/null
+++ b/model/vcs/spans.yaml
@@ -0,0 +1,39 @@
+groups:
+ - id: span.vcs.client
+ type: span
+ span_kind: client
+ stability: development
+ brief: >
+ This span describes a Version Control System (VCS) operation client, such as a Git CLI command or a CI/CD pipeline step cloning a repository.
+ note: |
+ VCS client spans are typically emitted by CI/CD pipeline steps executing VCS operations (e.g. checkout or clone tasks),
+ or by wrapper tools and CLI utilities performing Git, SVN, or Mercurial operations.
+
+ **Span name** MUST follow the overall [guidelines for span names](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#span).
+
+ The span name SHOULD follow the `{vcs.operation.name} {vcs.repository.name}` pattern,
+ or `{vcs.operation.name}` if target information is not applicable or available.
+ If the operation target is more specific (e.g. a branch or ref), the span name MAY be `{vcs.operation.name} {vcs.ref.head.name}`
+ or `{vcs.operation.name} {vcs.repository.name} {vcs.ref.head.name}`.
+
+ attributes:
+ - ref: vcs.operation.name
+ requirement_level: required
+ - ref: vcs.repository.name
+ requirement_level: required
+ - ref: vcs.repository.url.full
+ requirement_level: recommended
+ - ref: vcs.ref.head.name
+ requirement_level: recommended
+ - ref: vcs.ref.head.revision
+ requirement_level: recommended
+ - ref: vcs.ref.type
+ requirement_level: recommended
+ - ref: server.address
+ brief: The remote VCS server address (e.g. github.com, gitlab.com, or self-hosted Git server).
+ requirement_level: recommended
+ - ref: server.port
+ requirement_level: recommended
+ - ref: error.type
+ requirement_level:
+ conditionally_required: If the VCS operation fails.