Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ Increment the:
* [TEST] Shared otel-cpp libs linked to latest static protobuf and grpc
[#3544](https://github.com/open-telemetry/opentelemetry-cpp/pull/3544)

* [SDK] Implement env var configuration for PeriodicExportingMetricReader
[#3549](https://github.com/open-telemetry/opentelemetry-cpp/pull/3549)

## [1.22 2025-07-11]

* [DOC] Udpate link to membership document
Expand Down Expand Up @@ -1407,7 +1410,7 @@ Important changes:
* [ETW EXPORTER] Remove namespace using in ETW exporter which affects global
namespace
[#2531](https://github.com/open-telemetry/opentelemetry-cpp/pull/2531)
* [BUILD] Don't invoke vcpkg from this repo with CMAKE_TOOLCHAIN_FILE set
* [BUILD] Don't invoke vcpkg from this repo with CMAKE_TOOLCHAIN_FILE set
[#2527](https://github.com/open-telemetry/opentelemetry-cpp/pull/2527)
* [EXPORTER] Async exporting for otlp grpc
[#2407](https://github.com/open-telemetry/opentelemetry-cpp/pull/2407)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

#pragma once

#include "opentelemetry/version.h"

#include <chrono>

#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
Expand All @@ -16,18 +17,22 @@ namespace metrics
constexpr std::chrono::milliseconds kExportIntervalMillis = std::chrono::milliseconds(60000);
constexpr std::chrono::milliseconds kExportTimeOutMillis = std::chrono::milliseconds(30000);

std::chrono::milliseconds GetEnvDuration(nostd::string_view env_var_name,
std::chrono::milliseconds default_value);

/**
* Struct to hold PeriodicExortingMetricReader options.
*/

struct PeriodicExportingMetricReaderOptions
{
/* The time interval between two consecutive exports. */
std::chrono::milliseconds export_interval_millis =
std::chrono::milliseconds(kExportIntervalMillis);
std::chrono::milliseconds export_interval_millis;

/* how long the export can run before it is cancelled. */
std::chrono::milliseconds export_timeout_millis = std::chrono::milliseconds(kExportTimeOutMillis);
std::chrono::milliseconds export_timeout_millis;

PeriodicExportingMetricReaderOptions();
};

} // namespace metrics
Expand Down
1 change: 1 addition & 0 deletions sdk/src/metrics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_library(
instrument_metadata_validator.cc
export/periodic_exporting_metric_reader.cc
export/periodic_exporting_metric_reader_factory.cc
export/periodic_exporting_metric_reader_options.cc
state/filtered_ordered_attribute_map.cc
state/metric_collector.cc
state/observable_registry.cc
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include <chrono>

#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/sdk/common/env_variables.h"
#include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_options.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace metrics
{

std::chrono::milliseconds GetEnvDuration(nostd::string_view env_var_name,
std::chrono::milliseconds default_value)
{
std::chrono::system_clock::duration duration;
if (common::GetDurationEnvironmentVariable(env_var_name.data(), duration))
{
return std::chrono::duration_cast<std::chrono::milliseconds>(duration);
}
return default_value;
}
PeriodicExportingMetricReaderOptions::PeriodicExportingMetricReaderOptions()
: export_interval_millis(GetEnvDuration("OTEL_METRIC_EXPORT_INTERVAL", kExportIntervalMillis)),
export_timeout_millis(GetEnvDuration("OTEL_METRIC_EXPORT_TIMEOUT", kExportTimeOutMillis))
{}
} // namespace metrics
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
74 changes: 71 additions & 3 deletions sdk/test/metrics/periodic_exporting_metric_reader_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <stddef.h>
#include <chrono>
#include <memory>
#include <ratio>
#include <thread>
#include <utility>
#include <vector>
Expand All @@ -18,6 +17,11 @@
#include "opentelemetry/sdk/metrics/instruments.h"
#include "opentelemetry/sdk/metrics/push_metric_exporter.h"

#if defined(_MSC_VER)
using opentelemetry::common::setenv;
using opentelemetry::common::unsetenv;
#endif

using namespace opentelemetry;
using namespace opentelemetry::sdk::instrumentationscope;
using namespace opentelemetry::sdk::metrics;
Expand Down Expand Up @@ -76,7 +80,7 @@ class MockMetricProducer : public MetricProducer
size_t data_sent_size_{0};
};

TEST(PeriodicExporingMetricReader, BasicTests)
TEST(PeriodicExportingMetricReader, BasicTests)
{
std::unique_ptr<PushMetricExporter> exporter(
new MockPushMetricExporter(std::chrono::milliseconds{0}));
Expand All @@ -95,7 +99,7 @@ TEST(PeriodicExporingMetricReader, BasicTests)
static_cast<MockMetricProducer *>(&producer)->GetDataCount());
}

TEST(PeriodicExporingMetricReader, Timeout)
TEST(PeriodicExportingMetricReader, Timeout)
{
std::unique_ptr<PushMetricExporter> exporter(
new MockPushMetricExporter(std::chrono::milliseconds{2000}));
Expand All @@ -109,3 +113,67 @@ TEST(PeriodicExporingMetricReader, Timeout)
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
reader->Shutdown();
}

TEST(GetEnvDurationTest, Absent)
{
const char *env = "OTEL_TEST";
unsetenv(env);
EXPECT_EQ(GetEnvDuration(env, std::chrono::milliseconds(42)), std::chrono::milliseconds(42));
}

TEST(GetEnvDurationTest, NotSet)
{
const char *env = "OTEL_TEST";
setenv(env, "", 1);
EXPECT_EQ(GetEnvDuration(env, std::chrono::milliseconds(42)), std::chrono::milliseconds(42));
unsetenv(env);
}

TEST(GetEnvDurationTest, Valid)
{
const char *env = "OTEL_TEST";
setenv(env, "1243ms", 1);
EXPECT_EQ(GetEnvDuration(env, std::chrono::milliseconds(42)), std::chrono::milliseconds(1243));

setenv(env, "3s", 1);
EXPECT_EQ(GetEnvDuration(env, std::chrono::milliseconds(42)), std::chrono::milliseconds(3000));

unsetenv(env);
}

TEST(GetEnvDurationTest, Invalid)
{
const char *env = "OTEL_TEST";
setenv(env, "not_a_duration", 1);
EXPECT_EQ(GetEnvDuration(env, std::chrono::milliseconds(42)), std::chrono::milliseconds(42));
unsetenv(env);
}

TEST(PeriodicExportingMetricReaderOptions, UsesEnvVars)
{
const char *env_interval = "OTEL_METRIC_EXPORT_INTERVAL";
const char *env_timeout = "OTEL_METRIC_EXPORT_TIMEOUT";

setenv(env_interval, "1500ms", 1);
setenv(env_timeout, "1000ms", 1);

PeriodicExportingMetricReaderOptions options;
EXPECT_EQ(options.export_interval_millis, std::chrono::milliseconds(1500));
EXPECT_EQ(options.export_timeout_millis, std::chrono::milliseconds(1000));

unsetenv(env_interval);
unsetenv(env_timeout);
}

TEST(PeriodicExportingMetricReaderOptions, UsesDefault)
{
const char *env_interval = "OTEL_METRIC_EXPORT_INTERVAL";
const char *env_timeout = "OTEL_METRIC_EXPORT_TIMEOUT";

unsetenv(env_interval);
unsetenv(env_timeout);

PeriodicExportingMetricReaderOptions options;
EXPECT_EQ(options.export_interval_millis, std::chrono::milliseconds(60000));
EXPECT_EQ(options.export_timeout_millis, std::chrono::milliseconds(30000));
}
Loading