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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ Increment the:
* [CI] Upgrade tools/vcpkg to 2025.09.17
[#3701](https://github.com/open-telemetry/opentelemetry-cpp/pull/3701)

* [CONFIGURATION] File configuration - prometheus translation
[#3715](https://github.com/open-telemetry/opentelemetry-cpp/pull/3715)

## [1.23 2025-09-25]

* [CodeHealth] Fix clang-tidy warnings part 6
Expand Down
34 changes: 32 additions & 2 deletions exporters/prometheus/src/prometheus_pull_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
#include "opentelemetry/exporters/prometheus/exporter_factory.h"
#include "opentelemetry/exporters/prometheus/exporter_options.h"
#include "opentelemetry/exporters/prometheus/prometheus_pull_builder.h"
#include "opentelemetry/sdk/common/global_log_handler.h"
#include "opentelemetry/sdk/configuration/prometheus_pull_metric_exporter_builder.h"
#include "opentelemetry/sdk/configuration/prometheus_pull_metric_exporter_configuration.h"
#include "opentelemetry/sdk/configuration/registry.h"
#include "opentelemetry/sdk/configuration/translation_strategy.h"
#include "opentelemetry/sdk/metrics/metric_reader.h"
#include "opentelemetry/version.h"

Expand Down Expand Up @@ -38,8 +40,36 @@ std::unique_ptr<opentelemetry::sdk::metrics::MetricReader> PrometheusPullBuilder
options.url = url;
options.populate_target_info = true;
options.without_otel_scope = model->without_scope_info;
options.without_units = model->without_units;
options.without_type_suffix = model->without_type_suffix;

switch (model->translation_strategy)
{
case sdk::configuration::TranslationStrategy::UnderscoreEscapingWithSuffixes:
options.without_units = false;
options.without_type_suffix = false;
break;
case sdk::configuration::TranslationStrategy::UnderscoreEscapingWithoutSuffixes:
options.without_units = true;
options.without_type_suffix = true;
break;
case sdk::configuration::TranslationStrategy::NoUTF8EscapingWithSuffixes:
// FIXME: no flag to disable UnderscoreEscaping
OTEL_INTERNAL_LOG_WARN("[Prometheus Exporter] NoUTF8EscapingWithSuffixes not supported");
options.without_units = false;
options.without_type_suffix = false;
break;
case sdk::configuration::TranslationStrategy::NoTranslation:
// FIXME: no flag to disable UnderscoreEscaping
OTEL_INTERNAL_LOG_WARN("[Prometheus Exporter] NoTranslation not supported");
options.without_units = true;
options.without_type_suffix = true;
break;
}

if (model->with_resource_constant_labels != nullptr)
{
// FIXME: with_resource_constant_labels
OTEL_INTERNAL_LOG_WARN("[Prometheus Exporter] with_resource_constant_labels not supported");
}

return PrometheusExporterFactory::Create(options);
}
Expand Down
1 change: 1 addition & 0 deletions functional/configuration/shelltests/kitchen-sink.test
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ $ example_yaml --test --yaml shelltests/kitchen-sink.yaml | egrep -v "(observed_
MODEL PARSED
[WARNING] attribute_limits not supported, ignoring
[WARNING] IncludeExclude attribute processor not supported, ignoring
[WARNING] [Prometheus Exporter] with_resource_constant_labels not supported
[WARNING] metric producer not supported, ignoring
[WARNING] metric producer not supported, ignoring
[WARNING] [Periodic Exporting Metric Reader] Invalid configuration: export_timeout_millis_ should be less than export_interval_millis_, using default values
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

$ example_yaml --test --yaml shelltests/prometheus_translation_broken.yaml
>
[ERROR] <shelltests/prometheus_translation_broken.yaml>:9[10](164): Illegal TranslationStrategy: broken
FAILED TO PARSE MODEL
>= 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

file_format: "1.0"

meter_provider:
readers:
- pull:
exporter:
prometheus/development:
host: localhost
port: 9464
without_scope_info: false
# Must fail, invalid
translation_strategy: broken
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

$ example_yaml --test --yaml shelltests/prometheus_translation_no.yaml
>
MODEL PARSED
[WARNING] [Prometheus Exporter] NoTranslation not supported
[WARNING] [Prometheus Exporter] with_resource_constant_labels not supported
SDK CREATED
>= 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

file_format: "1.0"

meter_provider:
readers:
- pull:
exporter:
prometheus/development:
host: localhost
port: 9464
without_scope_info: false
translation_strategy: NoTranslation
with_resource_constant_labels:
included:
- "not supported"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

$ example_yaml --test --yaml shelltests/prometheus_translation_no_utf8.yaml
>
MODEL PARSED
[WARNING] [Prometheus Exporter] NoUTF8EscapingWithSuffixes not supported
SDK CREATED
>= 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

file_format: "1.0"

meter_provider:
readers:
- pull:
exporter:
prometheus/development:
host: localhost
port: 9464
without_scope_info: false
translation_strategy: NoUTF8EscapingWithSuffixes
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

$ example_yaml --test --yaml shelltests/prometheus_translation_with_suffixes.yaml
>
MODEL PARSED
SDK CREATED
>= 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

file_format: "1.0"

meter_provider:
readers:
- pull:
exporter:
prometheus/development:
host: localhost
port: 9464
without_scope_info: false
translation_strategy: UnderscoreEscapingWithSuffixes
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

$ example_yaml --test --yaml shelltests/prometheus_translation_without_suffixes.yaml
>
MODEL PARSED
SDK CREATED
>= 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0

file_format: "1.0"

meter_provider:
readers:
- pull:
exporter:
prometheus/development:
host: localhost
port: 9464
without_scope_info: false
translation_strategy: UnderscoreEscapingWithoutSuffixes
8 changes: 3 additions & 5 deletions install/test/src/test_exporters_prometheus_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ TEST(ExportersPrometheusBuilderInstall, PrometheusPullBuilder)
ASSERT_TRUE(builder != nullptr);

opentelemetry::sdk::configuration::PrometheusPullMetricExporterConfiguration model;
model.host = "localhost";
model.port = 1234;
model.without_scope_info = false;
model.without_units = false;
model.without_type_suffix = false;
model.host = "localhost";
model.port = 1234;
model.without_scope_info = false;

auto exporter = builder->Build(&model);
ASSERT_TRUE(exporter != nullptr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
#include "opentelemetry/sdk/configuration/temporality_preference.h"
#include "opentelemetry/sdk/configuration/trace_id_ratio_based_sampler_configuration.h"
#include "opentelemetry/sdk/configuration/tracer_provider_configuration.h"
#include "opentelemetry/sdk/configuration/translation_strategy.h"
#include "opentelemetry/sdk/configuration/view_configuration.h"
#include "opentelemetry/sdk/configuration/view_selector_configuration.h"
#include "opentelemetry/sdk/configuration/view_stream_configuration.h"
Expand Down Expand Up @@ -171,6 +172,9 @@ class ConfigurationParser
std::unique_ptr<ConsolePushMetricExporterConfiguration>
ParseConsolePushMetricExporterConfiguration(const std::unique_ptr<DocumentNode> &node) const;

TranslationStrategy ParseTranslationStrategy(const std::unique_ptr<DocumentNode> &node,
const std::string &name) const;

std::unique_ptr<PrometheusPullMetricExporterConfiguration>
ParsePrometheusPullMetricExporterConfiguration(const std::unique_ptr<DocumentNode> &node) const;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
#include <string>

#include "opentelemetry/sdk/configuration/headers_configuration.h"
#include "opentelemetry/sdk/configuration/include_exclude_configuration.h"
#include "opentelemetry/sdk/configuration/pull_metric_exporter_configuration.h"
#include "opentelemetry/sdk/configuration/pull_metric_exporter_configuration_visitor.h"
#include "opentelemetry/sdk/configuration/translation_strategy.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
Expand All @@ -28,10 +30,9 @@ class PrometheusPullMetricExporterConfiguration : public PullMetricExporterConfi

std::string host;
std::size_t port{0};
bool without_units{false};
bool without_type_suffix{false};
bool without_scope_info{false};
// FIXME: with_resource_constant_labels;
std::unique_ptr<IncludeExcludeConfiguration> with_resource_constant_labels;
TranslationStrategy translation_strategy;
};

} // namespace configuration
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <cstdint>

#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace configuration
{

// YAML-SCHEMA: schema/meter_provider.json
// YAML-NODE: ExperimentalPrometheusMetricExporter
enum class TranslationStrategy : std::uint8_t
{
UnderscoreEscapingWithSuffixes,
UnderscoreEscapingWithoutSuffixes,
NoUTF8EscapingWithSuffixes,
NoTranslation
};

} // namespace configuration
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
49 changes: 44 additions & 5 deletions sdk/src/configuration/configuration_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
#include "opentelemetry/sdk/configuration/temporality_preference.h"
#include "opentelemetry/sdk/configuration/trace_id_ratio_based_sampler_configuration.h"
#include "opentelemetry/sdk/configuration/tracer_provider_configuration.h"
#include "opentelemetry/sdk/configuration/translation_strategy.h"
#include "opentelemetry/sdk/configuration/view_configuration.h"
#include "opentelemetry/sdk/configuration/view_selector_configuration.h"
#include "opentelemetry/sdk/configuration/view_stream_configuration.h"
Expand Down Expand Up @@ -609,17 +610,55 @@ ConfigurationParser::ParseConsolePushMetricExporterConfiguration(
return model;
}

TranslationStrategy ConfigurationParser::ParseTranslationStrategy(
const std::unique_ptr<DocumentNode> &node,
const std::string &name) const
{
if (name == "UnderscoreEscapingWithSuffixes")
{
return TranslationStrategy::UnderscoreEscapingWithSuffixes;
}

if (name == "UnderscoreEscapingWithoutSuffixes")
{
return TranslationStrategy::UnderscoreEscapingWithoutSuffixes;
}

if (name == "NoUTF8EscapingWithSuffixes")
{
return TranslationStrategy::NoUTF8EscapingWithSuffixes;
}

if (name == "NoTranslation")
{
return TranslationStrategy::NoTranslation;
}

std::string message("Illegal TranslationStrategy: ");
message.append(name);
throw InvalidSchemaException(node->Location(), message);
}

std::unique_ptr<PrometheusPullMetricExporterConfiguration>
ConfigurationParser::ParsePrometheusPullMetricExporterConfiguration(
const std::unique_ptr<DocumentNode> &node) const
{
auto model = std::make_unique<PrometheusPullMetricExporterConfiguration>();
std::unique_ptr<DocumentNode> child;

model->host = node->GetString("host", "localhost");
model->port = node->GetInteger("port", 9464);
model->without_scope_info = node->GetBoolean("without_scope_info", false);

child = node->GetChildNode("with_resource_constant_labels");
if (child)
{
model->with_resource_constant_labels = ParseIncludeExcludeConfiguration(child);
}

model->host = node->GetString("host", "localhost");
model->port = node->GetInteger("port", 9464);
model->without_units = node->GetBoolean("without_units", false);
model->without_type_suffix = node->GetBoolean("without_type_suffix", false);
model->without_scope_info = node->GetBoolean("without_scope_info", false);
std::string translation_strategy =
node->GetString("translation_strategy", "UnderscoreEscapingWithSuffixes");
model->translation_strategy = ParseTranslationStrategy(node, translation_strategy);

return model;
}
Expand Down
Loading
Loading