Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,7 @@ functional/cert/server_cert_b.csr
functional/cert/server_cert_b.pem
functional/cert/server_cert_b-key.pem
functional/cert/unreadable.pem

# CodeQL build artifacts
_codeql_build_dir/
_codeql_detected_source_root
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
#pragma once

#include <chrono>
#include <cstddef>
#include <cstdint>

#include "opentelemetry/sdk/common/env_variables.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
Expand All @@ -14,33 +17,86 @@ namespace sdk
namespace trace
{

namespace batch_span_processor_options_env
{

inline size_t GetMaxQueueSizeFromEnv()
{
constexpr size_t kDefaultMaxQueueSize = 2048;
std::uint32_t value{};
if (!opentelemetry::sdk::common::GetUintEnvironmentVariable("OTEL_BSP_MAX_QUEUE_SIZE", value))
{
return kDefaultMaxQueueSize;
}
return static_cast<size_t>(value);
}

inline std::chrono::milliseconds GetScheduleDelayFromEnv()
{
const std::chrono::milliseconds kDefaultScheduleDelay{5000};
std::chrono::system_clock::duration duration{0};
if (!opentelemetry::sdk::common::GetDurationEnvironmentVariable("OTEL_BSP_SCHEDULE_DELAY",
duration))
{
return kDefaultScheduleDelay;
}
return std::chrono::duration_cast<std::chrono::milliseconds>(duration);
}

inline std::chrono::milliseconds GetExportTimeoutFromEnv()
{
const std::chrono::milliseconds kDefaultExportTimeout{30000};
std::chrono::system_clock::duration duration{0};
if (!opentelemetry::sdk::common::GetDurationEnvironmentVariable("OTEL_BSP_EXPORT_TIMEOUT",
duration))
{
return kDefaultExportTimeout;
}
return std::chrono::duration_cast<std::chrono::milliseconds>(duration);
}

inline size_t GetMaxExportBatchSizeFromEnv()
{
constexpr size_t kDefaultMaxExportBatchSize = 512;
std::uint32_t value{};
if (!opentelemetry::sdk::common::GetUintEnvironmentVariable("OTEL_BSP_MAX_EXPORT_BATCH_SIZE",
value))
{
return kDefaultMaxExportBatchSize;
}
return static_cast<size_t>(value);
}

} // namespace batch_span_processor_options_env

/**
* Struct to hold batch SpanProcessor options.
*/
struct OPENTELEMETRY_EXPORT BatchSpanProcessorOptions
{
BatchSpanProcessorOptions();
/**
* The maximum buffer/queue size. After the size is reached, spans are
* dropped.
*/
size_t max_queue_size;
size_t max_queue_size = batch_span_processor_options_env::GetMaxQueueSizeFromEnv();

/* The time interval between two consecutive exports. */
std::chrono::milliseconds schedule_delay_millis;
std::chrono::milliseconds schedule_delay_millis =
batch_span_processor_options_env::GetScheduleDelayFromEnv();

/**
* The maximum time allowed to to export data
* It is not currently used by the SDK and the parameter is ignored
* TODO: Implement the parameter in BatchSpanProcessor
*/
std::chrono::milliseconds export_timeout;
std::chrono::milliseconds export_timeout =
batch_span_processor_options_env::GetExportTimeoutFromEnv();

/**
* The maximum batch size of every export. It must be smaller or
* equal to max_queue_size.
*/
size_t max_export_batch_size;
size_t max_export_batch_size = batch_span_processor_options_env::GetMaxExportBatchSizeFromEnv();
};

} // namespace trace
Expand Down
71 changes: 5 additions & 66 deletions sdk/src/trace/batch_span_processor_options.cc
Original file line number Diff line number Diff line change
@@ -1,69 +1,8 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include <stddef.h>
#include <chrono>
#include <cstdint>

#include "opentelemetry/sdk/common/env_variables.h"
#include "opentelemetry/sdk/trace/batch_span_processor_options.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace trace
{

constexpr const char *kMaxQueueSizeEnv = "OTEL_BSP_MAX_QUEUE_SIZE";
constexpr const char *kScheduleDelayEnv = "OTEL_BSP_SCHEDULE_DELAY";
constexpr const char *kExportTimeoutEnv = "OTEL_BSP_EXPORT_TIMEOUT";
constexpr const char *kMaxExportBatchSizeEnv = "OTEL_BSP_MAX_EXPORT_BATCH_SIZE";

const size_t kDefaultMaxQueueSize = 2084;
const std::chrono::milliseconds kDefaultScheduleDelayMillis = std::chrono::milliseconds(5000);
const std::chrono::milliseconds kDefaultExportTimeout = std::chrono::milliseconds(3000);
const size_t kDefaultMaxExportBatchSize = 512;

inline size_t GetMaxQueueSizeFromEnv()
{
std::uint32_t value{};
if (!opentelemetry::sdk::common::GetUintEnvironmentVariable(kMaxQueueSizeEnv, value))
{
return kDefaultMaxQueueSize;
}
return static_cast<size_t>(value);
}

inline std::chrono::milliseconds GetDurationFromEnv(
const char *env_var,
const std::chrono::milliseconds &default_duration)
{
std::chrono::system_clock::duration duration{0};
if (!opentelemetry::sdk::common::GetDurationEnvironmentVariable(env_var, duration))
{
return default_duration;
}
return std::chrono::duration_cast<std::chrono::milliseconds>(duration);
}

inline size_t GetMaxExportBatchSizeFromEnv()
{
std::uint32_t value{};
if (!opentelemetry::sdk::common::GetUintEnvironmentVariable(kMaxExportBatchSizeEnv, value))
{
return kDefaultMaxExportBatchSize;
}
return static_cast<size_t>(value);
}

BatchSpanProcessorOptions::BatchSpanProcessorOptions()
: max_queue_size(GetMaxQueueSizeFromEnv()),
schedule_delay_millis(GetDurationFromEnv(kScheduleDelayEnv, kDefaultScheduleDelayMillis)),
export_timeout(GetDurationFromEnv(kExportTimeoutEnv, kDefaultExportTimeout)),
max_export_batch_size(GetMaxExportBatchSizeFromEnv())
{}

} // namespace trace
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
// This file is intentionally kept empty for ABI compatibility.
// BatchSpanProcessorOptions is now an aggregate type with default member initializers
// defined in the header file. The environment variable reading logic has been moved
// to inline helper functions in the header to restore C++20 aggregate initialization
// support (designated initializers).
60 changes: 58 additions & 2 deletions sdk/test/trace/batch_span_processor_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,9 @@ TEST(BatchSpanProcessorOptionsEnvTest, TestDefaultValues)
{
sdk::trace::BatchSpanProcessorOptions options;

EXPECT_EQ(options.max_queue_size, static_cast<size_t>(2084));
EXPECT_EQ(options.max_queue_size, static_cast<size_t>(2048));
EXPECT_EQ(options.schedule_delay_millis, std::chrono::milliseconds(5000));
EXPECT_EQ(options.export_timeout, std::chrono::milliseconds(3000));
EXPECT_EQ(options.export_timeout, std::chrono::milliseconds(30000));
EXPECT_EQ(options.max_export_batch_size, static_cast<size_t>(512));
}

Expand Down Expand Up @@ -445,4 +445,60 @@ TEST(BatchSpanProcessorOptionsEnvTest, TestOptionsReadFromMultipleEnvVars)
unsetenv("OTEL_BSP_MAX_EXPORT_BATCH_SIZE");
}

TEST(BatchSpanProcessorOptionsEnvTest, TestAggregateInitialization)
{
// Test aggregate initialization (brace initialization with partial fields)
// This validates that BatchSpanProcessorOptions is an aggregate type,
// which is required for C++20 designated initializers like:
// BatchSpanProcessorOptions{.max_queue_size = 100, .schedule_delay_millis = ...}

// Test default initialization
sdk::trace::BatchSpanProcessorOptions default_options{};
EXPECT_EQ(default_options.max_queue_size, static_cast<size_t>(2048));
EXPECT_EQ(default_options.schedule_delay_millis, std::chrono::milliseconds(5000));
EXPECT_EQ(default_options.export_timeout, std::chrono::milliseconds(30000));
EXPECT_EQ(default_options.max_export_batch_size, static_cast<size_t>(512));

// Test aggregate initialization with all fields explicitly set
sdk::trace::BatchSpanProcessorOptions custom_options{
100, // max_queue_size
std::chrono::milliseconds(200), // schedule_delay_millis
std::chrono::milliseconds(300), // export_timeout
50 // max_export_batch_size
};
EXPECT_EQ(custom_options.max_queue_size, static_cast<size_t>(100));
EXPECT_EQ(custom_options.schedule_delay_millis, std::chrono::milliseconds(200));
EXPECT_EQ(custom_options.export_timeout, std::chrono::milliseconds(300));
EXPECT_EQ(custom_options.max_export_batch_size, static_cast<size_t>(50));
}

#if __cplusplus >= 202002L
TEST(BatchSpanProcessorOptionsEnvTest, TestDesignatedInitializers)
{
// Test C++20 designated initializers
// This is the main use case that was broken by the constructor

sdk::trace::BatchSpanProcessorOptions options{
.max_queue_size = 1000,
.schedule_delay_millis = std::chrono::milliseconds(2000),
.export_timeout = std::chrono::milliseconds(3000),
.max_export_batch_size = 100};

EXPECT_EQ(options.max_queue_size, static_cast<size_t>(1000));
EXPECT_EQ(options.schedule_delay_millis, std::chrono::milliseconds(2000));
EXPECT_EQ(options.export_timeout, std::chrono::milliseconds(3000));
EXPECT_EQ(options.max_export_batch_size, static_cast<size_t>(100));

// Test partial designated initializers (only some fields)
sdk::trace::BatchSpanProcessorOptions partial_options{.max_queue_size = 500,
.max_export_batch_size = 50};

EXPECT_EQ(partial_options.max_queue_size, static_cast<size_t>(500));
// Default from env (or hardcoded default)
EXPECT_EQ(partial_options.schedule_delay_millis, std::chrono::milliseconds(5000));
EXPECT_EQ(partial_options.export_timeout, std::chrono::milliseconds(30000));
EXPECT_EQ(partial_options.max_export_batch_size, static_cast<size_t>(50));
}
#endif

OPENTELEMETRY_END_NAMESPACE
Loading