Skip to content

Commit

Permalink
Merge branch 'main' into fix_lifetime_in_log_record
Browse files Browse the repository at this point in the history
  • Loading branch information
owent authored Jan 31, 2025
2 parents 156c229 + 52a80b5 commit fabc4a0
Show file tree
Hide file tree
Showing 19 changed files with 658 additions and 34 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Increment the:

## [Unreleased]

* [SDK] Add tracer scope configurator
[#3137](https://github.com/open-telemetry/opentelemetry-cpp/pull/3137)

## [1.19 2025-01-22]

* [PROMETHEUS_EXPORTER] Fix default for emitting otel_scope attributes
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once
#include <functional>

#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace instrumentationscope
{
/**
* A scope configurator is a function that returns the scope config for a given instrumentation
* scope.
*/
template <typename T>
class ScopeConfigurator
{
public:
/**
* A builder class for the ScopeConfigurator that facilitates the creation of ScopeConfigurators.
*/
class Builder
{
public:
/**
* Constructor for a builder object that cam be used to create a scope configurator. A minimally
* configured builder would build a ScopeConfigurator that applies the default_scope_config to
* every instrumentation scope.
* @param default_scope_config The default scope config that the built configurator should fall
* back on.
*/
explicit Builder(T default_scope_config) noexcept : default_scope_config_(default_scope_config)
{}

/**
* Allows the user to pass a generic function that evaluates an instrumentation scope through a
* boolean check. If the check passes, the provided config is applied. Conditions are evaluated
* in order.
* @param scope_matcher a function that returns true if the scope being evaluated matches the
* criteria defined by the function.
* @param scope_config the scope configuration to return for the matched scope.
* @return this
*/
Builder &AddCondition(std::function<bool(const InstrumentationScope &)> scope_matcher,
T scope_config)
{
conditions_.emplace_back(scope_matcher, scope_config);
return *this;
}

/**
* A convenience condition that specifically matches the scope name of the scope being
* evaluated. If the scope name matches to the provided string, then the provided scope
* configuration is applied to the scope.
* @param scope_name The scope name to which the config needs to be applied.
* @param scope_config The scope config for the matching scopes.
* @return this
*/
Builder &AddConditionNameEquals(nostd::string_view scope_name, T scope_config)
{
std::function<bool(const InstrumentationScope &)> name_equals_matcher =
[scope_name = std::string(scope_name)](const InstrumentationScope &scope_info) {
return scope_info.GetName() == scope_name;
};
conditions_.emplace_back(name_equals_matcher, scope_config);
return *this;
}

/**
* Constructs the scope configurator object that can be used to retrieve scope config depending
* on the instrumentation scope.
* @return a configured scope configurator.
*/
ScopeConfigurator<T> Build() const
{
if (conditions_.size() == 0)
{
return ScopeConfigurator<T>(
[default_scope_config_ = this->default_scope_config_](const InstrumentationScope &) {
return default_scope_config_;
});
}

// Return a configurator that processes all the conditions
return ScopeConfigurator<T>(
[conditions_ = this->conditions_, default_scope_config_ = this->default_scope_config_](
const InstrumentationScope &scope_info) {
for (Condition condition : conditions_)
{
if (condition.scope_matcher(scope_info))
{
return condition.scope_config;
}
}
return default_scope_config_;
});
}

private:
/**
* An internal struct to encapsulate 'conditions' that can be applied to a
* ScopeConfiguratorBuilder. The applied conditions influence the behavior of the generated
* ScopeConfigurator.
*/
struct Condition
{
std::function<bool(const InstrumentationScope &)> scope_matcher;
T scope_config;

Condition(const std::function<bool(const InstrumentationScope &)> &matcher, const T &config)
: scope_matcher(matcher), scope_config(config)
{}
};

T default_scope_config_;
std::vector<Condition> conditions_;
};

// Public methods for ScopeConfigurator

/**
* Invokes the underlying configurator function to get a valid scope configuration.
* @param scope_info The InstrumentationScope containing scope information for which configuration
* needs to be retrieved.
*/
T ComputeConfig(const InstrumentationScope &scope_info) const
{
return this->configurator_(scope_info);
}

private:
// Prevent direct initialization of ScopeConfigurator objects.
explicit ScopeConfigurator(std::function<T(const InstrumentationScope &)> configurator)
: configurator_(configurator)
{}

std::function<T(const InstrumentationScope &)> configurator_;
};
} // namespace instrumentationscope
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
4 changes: 4 additions & 0 deletions sdk/include/opentelemetry/sdk/trace/tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#include "opentelemetry/sdk/trace/id_generator.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/sampler.h"
#include "opentelemetry/sdk/trace/tracer_config.h"
#include "opentelemetry/sdk/trace/tracer_context.h"
#include "opentelemetry/trace/noop.h"
#include "opentelemetry/trace/span.h"
#include "opentelemetry/trace/span_context_kv_iterable.h"
#include "opentelemetry/trace/span_startoptions.h"
Expand Down Expand Up @@ -105,6 +107,8 @@ class Tracer final : public opentelemetry::trace::Tracer,
// tracer-context.
std::shared_ptr<InstrumentationScope> instrumentation_scope_;
std::shared_ptr<TracerContext> context_;
TracerConfig tracer_config_;
static const std::shared_ptr<opentelemetry::trace::NoopTracer> kNoopTracer;
};
} // namespace trace
} // namespace sdk
Expand Down
59 changes: 59 additions & 0 deletions sdk/include/opentelemetry/sdk/trace/tracer_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace trace
{
/**
* TracerConfig defines various configurable aspects of a Tracer's behavior.
* This class should not be used directly to configure a Tracer's behavior, instead a
* ScopeConfigurator should be used to compute the desired TracerConfig which can then be used to
* configure a Tracer.
*/
class TracerConfig
{
public:
bool operator==(const TracerConfig &other) const noexcept;

/**
* Returns if the Tracer is enabled or disabled. Tracers are enabled by default.
* @return a boolean indicating if the Tracer is enabled. Defaults to true.
*/
bool IsEnabled() const noexcept;

/**
* Returns a TracerConfig that represents a disabled Tracer. A disabled tracer behaves like a
* no-op tracer.
* @return a static constant TracerConfig that represents a disabled tracer.
*/
static TracerConfig Disabled();

/**
* Returns a TracerConfig that represents an enabled Tracer.
* @return a static constant TracerConfig that represents an enabled tracer.
*/
static TracerConfig Enabled();

/**
* Returns a TracerConfig that represents a Tracer configured with the default behavior.
* The default behavior is guided by the OpenTelemetry specification.
* @return a static constant TracerConfig that represents a tracer configured with default
* behavior.
*/
static TracerConfig Default();

private:
explicit TracerConfig(const bool disabled = false) : disabled_(disabled) {}
bool disabled_;
static const TracerConfig kDefaultConfig;
static const TracerConfig kDisabledConfig;
};
} // namespace trace
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
17 changes: 16 additions & 1 deletion sdk/include/opentelemetry/sdk/trace/tracer_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
#include <memory>
#include <vector>

#include "opentelemetry/sdk/instrumentationscope/scope_configurator.h"
#include "opentelemetry/sdk/resource/resource.h"
#include "opentelemetry/sdk/trace/id_generator.h"
#include "opentelemetry/sdk/trace/processor.h"
#include "opentelemetry/sdk/trace/random_id_generator.h"
#include "opentelemetry/sdk/trace/sampler.h"
#include "opentelemetry/sdk/trace/samplers/always_on.h"
#include "opentelemetry/sdk/trace/tracer_config.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
Expand Down Expand Up @@ -43,7 +45,12 @@ class TracerContext
opentelemetry::sdk::resource::Resource::Create({}),
std::unique_ptr<Sampler> sampler = std::unique_ptr<AlwaysOnSampler>(new AlwaysOnSampler),
std::unique_ptr<IdGenerator> id_generator =
std::unique_ptr<IdGenerator>(new RandomIdGenerator())) noexcept;
std::unique_ptr<IdGenerator>(new RandomIdGenerator()),
std::unique_ptr<instrumentationscope::ScopeConfigurator<TracerConfig>> tracer_configurator =
std::make_unique<instrumentationscope::ScopeConfigurator<TracerConfig>>(
instrumentationscope::ScopeConfigurator<TracerConfig>::Builder(
TracerConfig::Default())
.Build())) noexcept;

virtual ~TracerContext() = default;

Expand Down Expand Up @@ -77,6 +84,13 @@ class TracerContext
*/
const opentelemetry::sdk::resource::Resource &GetResource() const noexcept;

/**
* Obtain the ScopeConfigurator with this tracer context.
* @return The ScopeConfigurator for this tracer context.
*/
const instrumentationscope::ScopeConfigurator<TracerConfig> &GetTracerConfigurator()
const noexcept;

/**
* Obtain the Id Generator associated with this tracer context.
* @return The ID Generator for this tracer context.
Expand All @@ -100,6 +114,7 @@ class TracerContext
std::unique_ptr<Sampler> sampler_;
std::unique_ptr<IdGenerator> id_generator_;
std::unique_ptr<SpanProcessor> processor_;
std::unique_ptr<instrumentationscope::ScopeConfigurator<TracerConfig>> tracer_configurator_;
};

} // namespace trace
Expand Down
10 changes: 10 additions & 0 deletions sdk/include/opentelemetry/sdk/trace/tracer_context_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ class OPENTELEMETRY_EXPORT TracerContextFactory
const opentelemetry::sdk::resource::Resource &resource,
std::unique_ptr<Sampler> sampler,
std::unique_ptr<IdGenerator> id_generator);

/**
* Create a TracerContext.
*/
static std::unique_ptr<TracerContext> Create(
std::vector<std::unique_ptr<SpanProcessor>> &&processors,
const opentelemetry::sdk::resource::Resource &resource,
std::unique_ptr<Sampler> sampler,
std::unique_ptr<IdGenerator> id_generator,
std::unique_ptr<instrumentationscope::ScopeConfigurator<TracerConfig>> tracer_configurator);
};

} // namespace trace
Expand Down
16 changes: 14 additions & 2 deletions sdk/include/opentelemetry/sdk/trace/tracer_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,34 @@ class OPENTELEMETRY_EXPORT TracerProvider final : public opentelemetry::trace::T
* not be a nullptr.
* @param id_generator The custom id generator for this tracer provider. This must
* not be a nullptr
* @param tracer_configurator Provides access to a function that computes the TracerConfig for
* Tracers provided by this TracerProvider.
*/
explicit TracerProvider(
std::unique_ptr<SpanProcessor> processor,
const opentelemetry::sdk::resource::Resource &resource =
opentelemetry::sdk::resource::Resource::Create({}),
std::unique_ptr<Sampler> sampler = std::unique_ptr<AlwaysOnSampler>(new AlwaysOnSampler),
std::unique_ptr<IdGenerator> id_generator =
std::unique_ptr<IdGenerator>(new RandomIdGenerator())) noexcept;
std::unique_ptr<IdGenerator>(new RandomIdGenerator()),
std::unique_ptr<instrumentationscope::ScopeConfigurator<TracerConfig>> tracer_configurator =
std::make_unique<instrumentationscope::ScopeConfigurator<TracerConfig>>(
instrumentationscope::ScopeConfigurator<TracerConfig>::Builder(
TracerConfig::Default())
.Build())) noexcept;

explicit TracerProvider(
std::vector<std::unique_ptr<SpanProcessor>> &&processors,
const opentelemetry::sdk::resource::Resource &resource =
opentelemetry::sdk::resource::Resource::Create({}),
std::unique_ptr<Sampler> sampler = std::unique_ptr<AlwaysOnSampler>(new AlwaysOnSampler),
std::unique_ptr<IdGenerator> id_generator =
std::unique_ptr<IdGenerator>(new RandomIdGenerator())) noexcept;
std::unique_ptr<IdGenerator>(new RandomIdGenerator()),
std::unique_ptr<instrumentationscope::ScopeConfigurator<TracerConfig>> tracer_configurator =
std::make_unique<instrumentationscope::ScopeConfigurator<TracerConfig>>(
instrumentationscope::ScopeConfigurator<TracerConfig>::Builder(
TracerConfig::Default())
.Build())) noexcept;

/**
* Initialize a new tracer provider with a specified context
Expand Down
18 changes: 16 additions & 2 deletions sdk/include/opentelemetry/sdk/trace/tracer_provider_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace trace
class OPENTELEMETRY_EXPORT TracerProviderFactory
{
public:
/* Serie of builders with a single processor. */
/* Series of creator methods with a single processor. */

static std::unique_ptr<opentelemetry::sdk::trace::TracerProvider> Create(
std::unique_ptr<SpanProcessor> processor);
Expand All @@ -48,7 +48,14 @@ class OPENTELEMETRY_EXPORT TracerProviderFactory
std::unique_ptr<Sampler> sampler,
std::unique_ptr<IdGenerator> id_generator);

/* Serie of builders with a vector of processor. */
static std::unique_ptr<opentelemetry::sdk::trace::TracerProvider> Create(
std::unique_ptr<SpanProcessor> processor,
const opentelemetry::sdk::resource::Resource &resource,
std::unique_ptr<Sampler> sampler,
std::unique_ptr<IdGenerator> id_generator,
std::unique_ptr<instrumentationscope::ScopeConfigurator<TracerConfig>> tracer_configurator);

/* Series of creator methods with a vector of processors. */

static std::unique_ptr<opentelemetry::sdk::trace::TracerProvider> Create(
std::vector<std::unique_ptr<SpanProcessor>> &&processors);
Expand All @@ -68,6 +75,13 @@ class OPENTELEMETRY_EXPORT TracerProviderFactory
std::unique_ptr<Sampler> sampler,
std::unique_ptr<IdGenerator> id_generator);

static std::unique_ptr<opentelemetry::sdk::trace::TracerProvider> Create(
std::vector<std::unique_ptr<SpanProcessor>> &&processors,
const opentelemetry::sdk::resource::Resource &resource,
std::unique_ptr<Sampler> sampler,
std::unique_ptr<IdGenerator> id_generator,
std::unique_ptr<instrumentationscope::ScopeConfigurator<TracerConfig>> tracer_configurator);

/* Create with a tracer context. */

static std::unique_ptr<opentelemetry::sdk::trace::TracerProvider> Create(
Expand Down
3 changes: 2 additions & 1 deletion sdk/src/trace/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ add_library(
samplers/trace_id_ratio.cc
samplers/trace_id_ratio_factory.cc
random_id_generator.cc
random_id_generator_factory.cc)
random_id_generator_factory.cc
tracer_config.cc)

set_target_properties(opentelemetry_trace PROPERTIES EXPORT_NAME trace)
set_target_version(opentelemetry_trace)
Expand Down
Loading

0 comments on commit fabc4a0

Please sign in to comment.