Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

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 @@ -46,6 +46,9 @@ Important changes:

* All the example code has been updated to reflect the new usage.

* [SDK] Implement spec: MetricFilter
[#3235](https://github.com/open-telemetry/opentelemetry-cpp/pull/3235)

## [1.19 2025-01-22]

* [PROMETHEUS_EXPORTER] Fix default for emitting otel_scope attributes
Expand Down
112 changes: 112 additions & 0 deletions sdk/include/opentelemetry/sdk/metrics/export/metric_filter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include <functional>
#include <memory>

#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
#include "opentelemetry/sdk/metrics/data/metric_data.h"
#include "opentelemetry/sdk/metrics/instruments.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace metrics
{

/**
* MetricFilter defines the interface which enables the MetricReader’s
* registered MetricProducers or the SDK’s MetricProducer to filter aggregated
* data points (Metric Points) inside its Produce operation. The filtering is
* done at the MetricProducer for performance reasons.
*
* The MetricFilter allows filtering an entire metric stream - dropping or
* allowing all its attribute sets - by its TestMetric operation, which accepts
* the metric stream information (scope, name, kind and unit) and returns an
* enumeration: kAccept, kDrop or kAcceptPartial. If the latter returned, the
* TestAttributes operation is to be called per attribute set of that metric
* stream, returning an enumeration determining if the data point for that
* (metric stream, attributes) pair is to be allowed in the result of the
* MetricProducer Produce operation.
*/
class MetricFilter
{
public:
enum class MetricFilterResult
{
kAccept,
kDrop,
kAcceptPartial,
};

enum class AttributesFilterResult
{
kAccept,
kDrop,
};

using TestMetricFn = std::function<MetricFilterResult(
const opentelemetry::sdk::instrumentationscope::InstrumentationScope &scope,
opentelemetry::nostd::string_view name,
const InstrumentType &type,
opentelemetry::nostd::string_view unit)>;

using TestAttributesFn = std::function<AttributesFilterResult(
const opentelemetry::sdk::instrumentationscope::InstrumentationScope &scope,
opentelemetry::nostd::string_view name,
const InstrumentType &type,
opentelemetry::nostd::string_view unit,
const PointAttributes &attributes)>;

// static
static std::unique_ptr<MetricFilter> Create(TestMetricFn test_metric_fn,
TestAttributesFn test_attributes_fn)
{
return std::make_unique<MetricFilter>(test_metric_fn, test_attributes_fn);
}

MetricFilter(TestMetricFn test_metric_fn, TestAttributesFn test_attributes_fn)
: test_metric_fn_(test_metric_fn), test_attributes_fn_(test_attributes_fn)
{}

/**
* TestMetric is called once for every metric stream, in each MetricProducer
* Produce operation.
*/
MetricFilterResult TestMetric(
const opentelemetry::sdk::instrumentationscope::InstrumentationScope &scope,
opentelemetry::nostd::string_view name,
const InstrumentType &type,
opentelemetry::nostd::string_view unit)
{
return test_metric_fn_(scope, name, type, unit);
}

/**
* TestAttributes determines for a given metric stream and attribute set if
* it should be allowed or filtered out.
*
* This operation should only be called if TestMetric operation returned
* kAcceptPartial for the given metric stream arguments.
*/
AttributesFilterResult TestAttributes(
const opentelemetry::sdk::instrumentationscope::InstrumentationScope &scope,
opentelemetry::nostd::string_view name,
const InstrumentType &type,
opentelemetry::nostd::string_view unit,
const PointAttributes &attributes)
{
return test_attributes_fn_(scope, name, type, unit, attributes);
}

private:
TestMetricFn test_metric_fn_;
TestAttributesFn test_attributes_fn_;
};

} // namespace metrics
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

#pragma once

#include <memory>
#include <utility>
#include <vector>

#include "opentelemetry/nostd/function_ref.h"
#include "opentelemetry/nostd/variant.h"
#include "opentelemetry/sdk/metrics/data/metric_data.h"
#include "opentelemetry/sdk/metrics/export/metric_filter.h"
#include "opentelemetry/version.h"

OPENTELEMETRY_BEGIN_NAMESPACE
Expand Down Expand Up @@ -80,7 +82,9 @@ struct ResourceMetrics
class MetricProducer
{
public:
MetricProducer() = default;
MetricProducer(std::unique_ptr<MetricFilter> metric_filter = nullptr)
: metric_filter_(std::move(metric_filter))
{}
virtual ~MetricProducer() = default;

MetricProducer(const MetricProducer &) = delete;
Expand All @@ -107,6 +111,8 @@ class MetricProducer
* partial failure.
*/
virtual Result Produce() noexcept = 0;

std::unique_ptr<MetricFilter> metric_filter_;
};

} // namespace metrics
Expand Down
22 changes: 17 additions & 5 deletions sdk/include/opentelemetry/sdk/metrics/meter_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "opentelemetry/nostd/span.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/sdk/instrumentationscope/scope_configurator.h"
#include "opentelemetry/sdk/metrics/export/metric_filter.h"
#include "opentelemetry/sdk/metrics/meter_config.h"
#include "opentelemetry/sdk/metrics/metric_reader.h"
#include "opentelemetry/sdk/metrics/state/metric_collector.h"
Expand All @@ -28,6 +29,11 @@
# include "opentelemetry/sdk/metrics/exemplar/filter_type.h"
#endif

namespace testing
{
class MetricCollectorTest;
}

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
Expand Down Expand Up @@ -107,14 +113,18 @@ class MeterContext : public std::enable_shared_from_this<MeterContext>
opentelemetry::common::SystemTimestamp GetSDKStartTime() noexcept;

/**
* Attaches a metric reader to list of configured readers for this Meter context.
* @param reader The metric reader for this meter context. This
* must not be a nullptr.
* Create a MetricCollector from a MetricReader using this MeterContext and add it to the list of
* configured collectors.
* @param reader The MetricReader for which a MetricCollector is to be created. This must not be a
* nullptr.
* @param metric_filter The optional MetricFilter used when creating the MetricCollector.
*
* Note: This reader may not receive any in-flight meter data, but will get newly created meter
* data. Note: This method is not thread safe, and should ideally be called from main thread.
* data.
* Note: This method is not thread safe, and should ideally be called from main thread.
*/
void AddMetricReader(std::shared_ptr<MetricReader> reader) noexcept;
void AddMetricReader(std::shared_ptr<MetricReader> reader,
std::unique_ptr<MetricFilter> metric_filter = nullptr) noexcept;

/**
* Attaches a View to list of configured Views for this Meter context.
Expand Down Expand Up @@ -161,6 +171,8 @@ class MeterContext : public std::enable_shared_from_this<MeterContext>
bool Shutdown(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept;

private:
friend class ::testing::MetricCollectorTest;

opentelemetry::sdk::resource::Resource resource_;
std::vector<std::shared_ptr<CollectorHandle>> collectors_;
std::unique_ptr<ViewRegistry> views_;
Expand Down
15 changes: 10 additions & 5 deletions sdk/include/opentelemetry/sdk/metrics/meter_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "opentelemetry/metrics/meter_provider.h"
#include "opentelemetry/nostd/shared_ptr.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/sdk/metrics/export/metric_filter.h"
#include "opentelemetry/sdk/metrics/meter_context.h"
#include "opentelemetry/sdk/metrics/metric_reader.h"
#include "opentelemetry/sdk/metrics/view/instrument_selector.h"
Expand Down Expand Up @@ -88,14 +89,18 @@ class OPENTELEMETRY_EXPORT MeterProvider final : public opentelemetry::metrics::
const sdk::resource::Resource &GetResource() const noexcept;

/**
* Attaches a metric reader to list of configured readers for this Meter providers.
* @param reader The metric reader for this meter provider. This
* must not be a nullptr.
* Create a MetricCollector from a MetricReader using the MeterContext of this MeterProvider and
* add it to the list of configured collectors.
* @param reader The MetricReader for which a MetricCollector is to be created. This must not be a
* nullptr.
* @param metric_filter The optional MetricFilter used when creating the MetricCollector.
*
* Note: This reader may not receive any in-flight meter data, but will get newly created meter
* data. Note: This method is not thread safe, and should ideally be called from main thread.
* data.
* Note: This method is not thread safe, and should ideally be called from main thread.
*/
void AddMetricReader(std::shared_ptr<MetricReader> reader) noexcept;
void AddMetricReader(std::shared_ptr<MetricReader> reader,
std::unique_ptr<MetricFilter> metric_filter = nullptr) noexcept;

/**
* Attaches a View to list of configured Views for this Meter provider.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <memory>

#include "opentelemetry/nostd/function_ref.h"
#include "opentelemetry/sdk/metrics/export/metric_filter.h"
#include "opentelemetry/sdk/metrics/export/metric_producer.h"
#include "opentelemetry/sdk/metrics/instruments.h"
#include "opentelemetry/sdk/metrics/metric_reader.h"
Expand Down Expand Up @@ -40,7 +41,9 @@ class CollectorHandle
class MetricCollector : public MetricProducer, public CollectorHandle
{
public:
MetricCollector(MeterContext *context, std::shared_ptr<MetricReader> metric_reader);
MetricCollector(MeterContext *context,
std::shared_ptr<MetricReader> metric_reader,
std::unique_ptr<MetricFilter> metric_filter = nullptr);

~MetricCollector() override = default;

Expand All @@ -62,6 +65,7 @@ class MetricCollector : public MetricProducer, public CollectorHandle
private:
MeterContext *meter_context_;
std::shared_ptr<MetricReader> metric_reader_;
std::unique_ptr<MetricFilter> metric_filter_;
};
} // namespace metrics
} // namespace sdk
Expand Down
7 changes: 5 additions & 2 deletions sdk/src/metrics/meter_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "opentelemetry/sdk/common/global_log_handler.h"
#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
#include "opentelemetry/sdk/instrumentationscope/scope_configurator.h"
#include "opentelemetry/sdk/metrics/export/metric_filter.h"
#include "opentelemetry/sdk/metrics/meter.h"
#include "opentelemetry/sdk/metrics/meter_config.h"
#include "opentelemetry/sdk/metrics/meter_context.h"
Expand Down Expand Up @@ -92,9 +93,11 @@ opentelemetry::common::SystemTimestamp MeterContext::GetSDKStartTime() noexcept
return sdk_start_ts_;
}

void MeterContext::AddMetricReader(std::shared_ptr<MetricReader> reader) noexcept
void MeterContext::AddMetricReader(std::shared_ptr<MetricReader> reader,
std::unique_ptr<MetricFilter> metric_filter) noexcept
{
auto collector = std::shared_ptr<MetricCollector>{new MetricCollector(this, std::move(reader))};
auto collector = std::shared_ptr<MetricCollector>{
new MetricCollector(this, std::move(reader), std::move(metric_filter))};
collectors_.push_back(collector);
}

Expand Down
6 changes: 4 additions & 2 deletions sdk/src/metrics/meter_provider.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "opentelemetry/sdk/common/global_log_handler.h"
#include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
#include "opentelemetry/sdk/instrumentationscope/scope_configurator.h"
#include "opentelemetry/sdk/metrics/export/metric_filter.h"
#include "opentelemetry/sdk/metrics/meter.h"
#include "opentelemetry/sdk/metrics/meter_config.h"
#include "opentelemetry/sdk/metrics/meter_context.h"
Expand Down Expand Up @@ -112,9 +113,10 @@ const resource::Resource &MeterProvider::GetResource() const noexcept
return context_->GetResource();
}

void MeterProvider::AddMetricReader(std::shared_ptr<MetricReader> reader) noexcept
void MeterProvider::AddMetricReader(std::shared_ptr<MetricReader> reader,
std::unique_ptr<MetricFilter> metric_filter) noexcept
{
context_->AddMetricReader(std::move(reader));
context_->AddMetricReader(std::move(reader), std::move(metric_filter));
}

void MeterProvider::AddView(std::unique_ptr<InstrumentSelector> instrument_selector,
Expand Down
Loading
Loading