Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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 @@ -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