Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ Increment the:
* [BUILD] Upgrade to opentelemetry-proto 1.8.0
[#3730](https://github.com/open-telemetry/opentelemetry-cpp/pull/3730)

New Features:

* [CONFIGURATION] Implement declarative configuration (config.yaml)
[#2518](https://github.com/open-telemetry/opentelemetry-cpp/pull/2518)

* Configuration for opentelemetry-cpp can now be done using a config.yaml
file, instead of using environment variables.
* See [opentelemetry-configuration](https://github.com/open-telemetry/opentelemetry-configuration)

## [1.23 2025-09-25]

* [CodeHealth] Fix clang-tidy warnings part 6
Expand Down
48 changes: 30 additions & 18 deletions api/include/opentelemetry/semconv/http_attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,23 @@ static constexpr const char *kHttpRequestHeader = "http.request.header";
<p>
HTTP request method value SHOULD be "known" to the instrumentation.
By default, this convention defines "known" methods as the ones listed in <a
href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a> and the PATCH method
defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a>. <p> If the HTTP
request method is not known to instrumentation, it MUST set the @code http.request.method @endcode
attribute to @code _OTHER @endcode. <p> If the HTTP instrumentation could end up converting valid
HTTP request methods to @code _OTHER @endcode, then it MUST provide a way to override the list of
known HTTP methods. If this override is done via environment variable, then the environment
variable MUST be named OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list
of case-sensitive known HTTP methods (this list MUST be a full override of the default known
method, it is not a list of known methods in addition to the defaults). <p> HTTP method names are
case-sensitive and @code http.request.method @endcode attribute value MUST match a known HTTP
method name exactly. Instrumentations for specific web frameworks that consider HTTP methods to be
case insensitive, SHOULD populate a canonical equivalent. Tracing instrumentations that do so,
MUST also set @code http.request.method_original @endcode to the original value.
href="https://www.rfc-editor.org/rfc/rfc9110.html#name-methods">RFC9110</a>, the PATCH method
defined in <a href="https://www.rfc-editor.org/rfc/rfc5789.html">RFC5789</a> and the QUERY method
defined in <a
href="https://datatracker.ietf.org/doc/draft-ietf-httpbis-safe-method-w-body/?include_text=1">httpbis-safe-method-w-body</a>.
<p>
If the HTTP request method is not known to instrumentation, it MUST set the @code
http.request.method @endcode attribute to @code _OTHER @endcode. <p> If the HTTP instrumentation
could end up converting valid HTTP request methods to @code _OTHER @endcode, then it MUST provide
a way to override the list of known HTTP methods. If this override is done via environment
variable, then the environment variable MUST be named OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and
support a comma-separated list of case-sensitive known HTTP methods (this list MUST be a full
override of the default known method, it is not a list of known methods in addition to the
defaults). <p> HTTP method names are case-sensitive and @code http.request.method @endcode
attribute value MUST match a known HTTP method name exactly. Instrumentations for specific web
frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical
equivalent. Tracing instrumentations that do so, MUST also set @code http.request.method_original
@endcode to the original value.
*/
static constexpr const char *kHttpRequestMethod = "http.request.method";

Expand Down Expand Up @@ -97,11 +101,19 @@ static constexpr const char *kHttpResponseHeader = "http.response.header";
static constexpr const char *kHttpResponseStatusCode = "http.response.status_code";

/**
The matched route, that is, the path template in the format used by the respective server
framework. <p> MUST NOT be populated when this is not supported by the HTTP server framework as
the route attribute should have low-cardinality and the URI path can NOT substitute it. SHOULD
include the <a href="/docs/http/http-spans.md#http-server-definitions">application root</a> if
there is one.
The matched route template for the request. This MUST be low-cardinality and include all static
path segments, with dynamic path segments represented with placeholders. <p> MUST NOT be populated
when this is not supported by the HTTP server framework as the route attribute should have
low-cardinality and the URI path can NOT substitute it. SHOULD include the <a
href="/docs/http/http-spans.md#http-server-definitions">application root</a> if there is one. <p>
A static path segment is a part of the route template with a fixed, low-cardinality value. This
includes literal strings like @code /users/ @endcode and placeholders that are constrained to a
finite, predefined set of values, e.g. @code {controller} @endcode or @code {action} @endcode. <p>
A dynamic path segment is a placeholder for a value that can have high cardinality and is not
constrained to a predefined list like static path segments. <p> Instrumentations SHOULD use
routing information provided by the corresponding web framework. They SHOULD pick the most precise
source of routing information and MAY support custom route formatting. Instrumentations SHOULD
document the format and the API used to obtain the route string.
*/
static constexpr const char *kHttpRoute = "http.route";

Expand Down
18 changes: 18 additions & 0 deletions api/include/opentelemetry/semconv/incubating/app_attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,24 @@ static constexpr const char *kAppScreenCoordinateX = "app.screen.coordinate.x";
*/
static constexpr const char *kAppScreenCoordinateY = "app.screen.coordinate.y";

/**
An identifier that uniquely differentiates this screen from other screens in the same application.
<p>
A screen represents only the part of the device display drawn by the app. It typically contains
multiple widgets or UI components and is larger in scope than individual widgets. Multiple screens
can coexist on the same display simultaneously (e.g., split view on tablets).
*/
static constexpr const char *kAppScreenId = "app.screen.id";

/**
The name of an application screen.
<p>
A screen represents only the part of the device display drawn by the app. It typically contains
multiple widgets or UI components and is larger in scope than individual widgets. Multiple screens
can coexist on the same display simultaneously (e.g., split view on tablets).
*/
static constexpr const char *kAppScreenName = "app.screen.name";

/**
An identifier that uniquely differentiates this widget from other widgets in the same application.
<p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ static constexpr const char *kAzureCosmosdbConsistencyLevel = "azure.cosmosdb.co
List of regions contacted during operation in the order that they were contacted. If there is more
than one region listed, it indicates that the operation was performed on multiple regions i.e.
cross-regional call. <p> Region name matches the format of @code displayName @endcode in <a
href="https://learn.microsoft.com/rest/api/subscription/subscriptions/list-locations?view=rest-subscription-2021-10-01&tabs=HTTP#location">Azure
Location API</a>
href="https://learn.microsoft.com/rest/api/resources/subscriptions/list-locations">Azure Location
API</a>
*/
static constexpr const char *kAzureCosmosdbOperationContactedRegions =
"azure.cosmosdb.operation.contacted_regions";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static constexpr const char *kContainerId = "container.id";
<p>
Docker defines a sha256 of the image id; @code container.image.id @endcode corresponds to the
@code Image @endcode field from the Docker container inspect <a
href="https://docs.docker.com/engine/api/v1.43/#tag/Container/operation/ContainerInspect">API</a>
href="https://docs.docker.com/reference/api/engine/version/v1.43/#tag/Container/operation/ContainerInspect">API</a>
endpoint. K8s defines a link to the container registry repository with digest @code "imageID":
"registry.azurecr.io
/namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"
Expand All @@ -91,7 +91,8 @@ static constexpr const char *kContainerImageName = "container.image.name";
/**
Repo digests of the container image as provided by the container runtime.
<p>
<a href="https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect">Docker</a>
<a
href="https://docs.docker.com/reference/api/engine/version/v1.43/#tag/Image/operation/ImageInspect">Docker</a>
and <a
href="https://github.com/kubernetes/cri-api/blob/c75ef5b473bbe2d0a4fc92f82235efd665ea8e9f/pkg/apis/runtime/v1/api.proto#L1237-L1238">CRI</a>
report those under the @code RepoDigests @endcode field.
Expand All @@ -100,9 +101,9 @@ static constexpr const char *kContainerImageRepoDigests = "container.image.repo_

/**
Container image tags. An example can be found in <a
href="https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect">Docker Image
Inspect</a>. Should be only the @code <tag> @endcode section of the full name for example from
@code registry.example.com/my-org/my-image:<tag> @endcode.
href="https://docs.docker.com/reference/api/engine/version/v1.43/#tag/Image/operation/ImageInspect">Docker
Image Inspect</a>. Should be only the @code <tag> @endcode section of the full name for example
from @code registry.example.com/my-org/my-image:<tag> @endcode.
*/
static constexpr const char *kContainerImageTags = "container.image.tags";

Expand Down
193 changes: 193 additions & 0 deletions api/include/opentelemetry/semconv/incubating/container_metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,151 @@ CreateAsyncDoubleMetricContainerFilesystemUsage(metrics::Meter *meter)
unitMetricContainerFilesystemUsage);
}

/**
Container memory available.
<p>
Available memory for use. This is defined as the memory limit - workingSetBytes. If memory limit
is undefined, the available bytes is omitted. In general, this metric can be derived from <a
href="https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics">cadvisor</a>
and by subtracting the @code container_memory_working_set_bytes @endcode metric from the @code
container_spec_memory_limit_bytes @endcode metric. In K8s, this metric is derived from the <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#MemoryStats">MemoryStats.AvailableBytes</a>
field of the <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#PodStats">PodStats.Memory</a>
of the Kubelet's stats API. <p> updowncounter
*/
static constexpr const char *kMetricContainerMemoryAvailable = "container.memory.available";
static constexpr const char *descrMetricContainerMemoryAvailable = "Container memory available.";
static constexpr const char *unitMetricContainerMemoryAvailable = "By";

static inline nostd::unique_ptr<metrics::UpDownCounter<int64_t>>
CreateSyncInt64MetricContainerMemoryAvailable(metrics::Meter *meter)
{
return meter->CreateInt64UpDownCounter(kMetricContainerMemoryAvailable,
descrMetricContainerMemoryAvailable,
unitMetricContainerMemoryAvailable);
}

static inline nostd::unique_ptr<metrics::UpDownCounter<double>>
CreateSyncDoubleMetricContainerMemoryAvailable(metrics::Meter *meter)
{
return meter->CreateDoubleUpDownCounter(kMetricContainerMemoryAvailable,
descrMetricContainerMemoryAvailable,
unitMetricContainerMemoryAvailable);
}

static inline nostd::shared_ptr<metrics::ObservableInstrument>
CreateAsyncInt64MetricContainerMemoryAvailable(metrics::Meter *meter)
{
return meter->CreateInt64ObservableUpDownCounter(kMetricContainerMemoryAvailable,
descrMetricContainerMemoryAvailable,
unitMetricContainerMemoryAvailable);
}

static inline nostd::shared_ptr<metrics::ObservableInstrument>
CreateAsyncDoubleMetricContainerMemoryAvailable(metrics::Meter *meter)
{
return meter->CreateDoubleObservableUpDownCounter(kMetricContainerMemoryAvailable,
descrMetricContainerMemoryAvailable,
unitMetricContainerMemoryAvailable);
}

/**
Container memory paging faults.
<p>
In general, this metric can be derived from <a
href="https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics">cadvisor</a>
and specifically the @code container_memory_failures_total{failure_type=pgfault, scope=container}
@endcode and @code container_memory_failures_total{failure_type=pgmajfault, scope=container}
@endcodemetric. In K8s, this metric is derived from the <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#MemoryStats">MemoryStats.PageFaults</a>
and <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#MemoryStats">MemoryStats.MajorPageFaults</a>
field of the <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#PodStats">PodStats.Memory</a>
of the Kubelet's stats API. <p> counter
*/
static constexpr const char *kMetricContainerMemoryPagingFaults = "container.memory.paging.faults";
static constexpr const char *descrMetricContainerMemoryPagingFaults =
"Container memory paging faults.";
static constexpr const char *unitMetricContainerMemoryPagingFaults = "{fault}";

static inline nostd::unique_ptr<metrics::Counter<uint64_t>>
CreateSyncInt64MetricContainerMemoryPagingFaults(metrics::Meter *meter)
{
return meter->CreateUInt64Counter(kMetricContainerMemoryPagingFaults,
descrMetricContainerMemoryPagingFaults,
unitMetricContainerMemoryPagingFaults);
}

static inline nostd::unique_ptr<metrics::Counter<double>>
CreateSyncDoubleMetricContainerMemoryPagingFaults(metrics::Meter *meter)
{
return meter->CreateDoubleCounter(kMetricContainerMemoryPagingFaults,
descrMetricContainerMemoryPagingFaults,
unitMetricContainerMemoryPagingFaults);
}

static inline nostd::shared_ptr<metrics::ObservableInstrument>
CreateAsyncInt64MetricContainerMemoryPagingFaults(metrics::Meter *meter)
{
return meter->CreateInt64ObservableCounter(kMetricContainerMemoryPagingFaults,
descrMetricContainerMemoryPagingFaults,
unitMetricContainerMemoryPagingFaults);
}

static inline nostd::shared_ptr<metrics::ObservableInstrument>
CreateAsyncDoubleMetricContainerMemoryPagingFaults(metrics::Meter *meter)
{
return meter->CreateDoubleObservableCounter(kMetricContainerMemoryPagingFaults,
descrMetricContainerMemoryPagingFaults,
unitMetricContainerMemoryPagingFaults);
}

/**
Container memory RSS.
<p>
In general, this metric can be derived from <a
href="https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics">cadvisor</a>
and specifically the @code container_memory_rss @endcode metric. In K8s, this metric is derived
from the <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#MemoryStats">MemoryStats.RSSBytes</a>
field of the <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#PodStats">PodStats.Memory</a>
of the Kubelet's stats API. <p> updowncounter
*/
static constexpr const char *kMetricContainerMemoryRss = "container.memory.rss";
static constexpr const char *descrMetricContainerMemoryRss = "Container memory RSS.";
static constexpr const char *unitMetricContainerMemoryRss = "By";

static inline nostd::unique_ptr<metrics::UpDownCounter<int64_t>>
CreateSyncInt64MetricContainerMemoryRss(metrics::Meter *meter)
{
return meter->CreateInt64UpDownCounter(kMetricContainerMemoryRss, descrMetricContainerMemoryRss,
unitMetricContainerMemoryRss);
}

static inline nostd::unique_ptr<metrics::UpDownCounter<double>>
CreateSyncDoubleMetricContainerMemoryRss(metrics::Meter *meter)
{
return meter->CreateDoubleUpDownCounter(kMetricContainerMemoryRss, descrMetricContainerMemoryRss,
unitMetricContainerMemoryRss);
}

static inline nostd::shared_ptr<metrics::ObservableInstrument>
CreateAsyncInt64MetricContainerMemoryRss(metrics::Meter *meter)
{
return meter->CreateInt64ObservableUpDownCounter(
kMetricContainerMemoryRss, descrMetricContainerMemoryRss, unitMetricContainerMemoryRss);
}

static inline nostd::shared_ptr<metrics::ObservableInstrument>
CreateAsyncDoubleMetricContainerMemoryRss(metrics::Meter *meter)
{
return meter->CreateDoubleObservableUpDownCounter(
kMetricContainerMemoryRss, descrMetricContainerMemoryRss, unitMetricContainerMemoryRss);
}

/**
Memory usage of the container.
<p>
Expand Down Expand Up @@ -328,6 +473,54 @@ CreateAsyncDoubleMetricContainerMemoryUsage(metrics::Meter *meter)
kMetricContainerMemoryUsage, descrMetricContainerMemoryUsage, unitMetricContainerMemoryUsage);
}

/**
Container memory working set.
<p>
In general, this metric can be derived from <a
href="https://github.com/google/cadvisor/blob/v0.53.0/docs/storage/prometheus.md#prometheus-container-metrics">cadvisor</a>
and specifically the @code container_memory_working_set_bytes @endcode metric. In K8s, this metric
is derived from the <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#MemoryStats">MemoryStats.WorkingSetBytes</a>
field of the <a
href="https://pkg.go.dev/k8s.io/[email protected]/pkg/apis/stats/v1alpha1#PodStats">PodStats.Memory</a>
of the Kubelet's stats API. <p> updowncounter
*/
static constexpr const char *kMetricContainerMemoryWorkingSet = "container.memory.working_set";
static constexpr const char *descrMetricContainerMemoryWorkingSet = "Container memory working set.";
static constexpr const char *unitMetricContainerMemoryWorkingSet = "By";

static inline nostd::unique_ptr<metrics::UpDownCounter<int64_t>>
CreateSyncInt64MetricContainerMemoryWorkingSet(metrics::Meter *meter)
{
return meter->CreateInt64UpDownCounter(kMetricContainerMemoryWorkingSet,
descrMetricContainerMemoryWorkingSet,
unitMetricContainerMemoryWorkingSet);
}

static inline nostd::unique_ptr<metrics::UpDownCounter<double>>
CreateSyncDoubleMetricContainerMemoryWorkingSet(metrics::Meter *meter)
{
return meter->CreateDoubleUpDownCounter(kMetricContainerMemoryWorkingSet,
descrMetricContainerMemoryWorkingSet,
unitMetricContainerMemoryWorkingSet);
}

static inline nostd::shared_ptr<metrics::ObservableInstrument>
CreateAsyncInt64MetricContainerMemoryWorkingSet(metrics::Meter *meter)
{
return meter->CreateInt64ObservableUpDownCounter(kMetricContainerMemoryWorkingSet,
descrMetricContainerMemoryWorkingSet,
unitMetricContainerMemoryWorkingSet);
}

static inline nostd::shared_ptr<metrics::ObservableInstrument>
CreateAsyncDoubleMetricContainerMemoryWorkingSet(metrics::Meter *meter)
{
return meter->CreateDoubleObservableUpDownCounter(kMetricContainerMemoryWorkingSet,
descrMetricContainerMemoryWorkingSet,
unitMetricContainerMemoryWorkingSet);
}

/**
Network bytes for the container.
<p>
Expand Down
Loading
Loading