Skip to content

Commit

Permalink
metrics exemplar round 1 (#1264)
Browse files Browse the repository at this point in the history
  • Loading branch information
esigo authored Mar 24, 2022
1 parent 0c9aece commit 3c7b44b
Show file tree
Hide file tree
Showing 28 changed files with 787 additions and 113 deletions.
17 changes: 15 additions & 2 deletions api/include/opentelemetry/metrics/noop.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ class NoopCounter : public Counter<T>
nostd::string_view unit) noexcept
{}
void Add(T value) noexcept override {}
void Add(T value, const opentelemetry::context::Context &context) noexcept override {}
void Add(T value, const common::KeyValueIterable &attributes) noexcept override {}
void Add(T value,
const common::KeyValueIterable &attributes,
const opentelemetry::context::Context &context) noexcept override
{}
};

template <class T>
Expand All @@ -35,8 +40,11 @@ class NoopHistogram : public Histogram<T>
nostd::string_view description,
nostd::string_view unit) noexcept
{}
void Record(T value) noexcept override {}
void Record(T value, const common::KeyValueIterable &attributes) noexcept override {}
void Record(T value, const opentelemetry::context::Context &context) noexcept override {}
void Record(T value,
const common::KeyValueIterable &attributes,
const opentelemetry::context::Context &context) noexcept override
{}
};

template <class T>
Expand All @@ -48,7 +56,12 @@ class NoopUpDownCounter : public UpDownCounter<T>
nostd::string_view unit) noexcept
{}
void Add(T value) noexcept override {}
void Add(T value, const opentelemetry::context::Context &context) noexcept override {}
void Add(T value, const common::KeyValueIterable &attributes) noexcept override {}
void Add(T value,
const common::KeyValueIterable &attributes,
const opentelemetry::context::Context &context) noexcept override
{}
};

template <class T>
Expand Down
90 changes: 75 additions & 15 deletions api/include/opentelemetry/metrics/sync_instruments.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

# include "opentelemetry/common/attribute_value.h"
# include "opentelemetry/common/key_value_iterable_view.h"
# include "opentelemetry/context/context.h"
# include "opentelemetry/nostd/span.h"
# include "opentelemetry/nostd/string_view.h"
# include "opentelemetry/nostd/type_traits.h"
Expand All @@ -29,6 +30,8 @@ class Counter : public SynchronousInstrument
*/
virtual void Add(T value) noexcept = 0;

virtual void Add(T value, const opentelemetry::context::Context &context) noexcept = 0;

/**
* Add adds the value to the counter's sum. The attributes should contain
* the keys and values to be associated with this value. Counters only
Expand All @@ -40,19 +43,44 @@ class Counter : public SynchronousInstrument

virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0;

virtual void Add(T value,
const common::KeyValueIterable &attributes,
const opentelemetry::context::Context &context) noexcept = 0;

template <class U,
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr>
void Add(T value, const U &attributes) noexcept
{
this->Add(value, common::KeyValueIterableView<U>{attributes});
auto context = opentelemetry::context::Context{};
this->Add(value, common::KeyValueIterableView<U>{attributes}, context);
}

template <class U,
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr>
void Add(T value, const U &attributes, const opentelemetry::context::Context &context) noexcept
{
this->Add(value, common::KeyValueIterableView<U>{attributes}, context);
}

void Add(T value,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>
attributes) noexcept
{
this->Add(value, nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()});
auto context = opentelemetry::context::Context{};
this->Add(value,
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()},
context);
}

void Add(T value,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
const opentelemetry::context::Context &context) noexcept
{
this->Add(value,
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()},
context);
}
};

Expand All @@ -67,29 +95,34 @@ class Histogram : public SynchronousInstrument
*
* @param value The increment amount. May be positive, negative or zero.
*/
virtual void Record(T value) noexcept = 0;
virtual void Record(T value, const opentelemetry::context::Context &context) noexcept = 0;

/**
* Records a value with a set of attributes.
*
* @param value The increment amount. May be positive, negative or zero.
* @param attributes A set of attributes to associate with the count.
*/
virtual void Record(T value, const common::KeyValueIterable &attributes) noexcept = 0;
virtual void Record(T value,
const common::KeyValueIterable &attributes,
const opentelemetry::context::Context &context) noexcept = 0;

template <class U,
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr>
void Record(T value, const U &attributes) noexcept
void Record(T value, const U &attributes, const opentelemetry::context::Context &context) noexcept
{
this->Record(value, common::KeyValueIterableView<U>{attributes});
this->Record(value, common::KeyValueIterableView<U>{attributes}, context);
}

void Record(T value,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>
attributes) noexcept
void Record(
T value,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
const opentelemetry::context::Context &context) noexcept
{
this->Record(value, nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()});
this->Record(value,
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()},
context);
}
};

Expand All @@ -106,6 +139,8 @@ class UpDownCounter : public SynchronousInstrument
*/
virtual void Add(T value) noexcept = 0;

virtual void Add(T value, const opentelemetry::context::Context &context) noexcept = 0;

/**
* Add a value with a set of attributes.
*
Expand All @@ -114,19 +149,44 @@ class UpDownCounter : public SynchronousInstrument
*/
virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0;

virtual void Add(T value,
const common::KeyValueIterable &attributes,
const opentelemetry::context::Context &context) noexcept = 0;

template <class U,
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr>
void Add(T value, const U &attributes) noexcept
{
this->Add(value, common::KeyValueIterableView<U>{attributes});
auto context = opentelemetry::context::Context{};
this->Add(value, common::KeyValueIterableView<U>{attributes}, context);
}

template <class U,
nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr>
void Add(T value, const U &attributes, const opentelemetry::context::Context &context) noexcept
{
this->Add(value, common::KeyValueIterableView<U>{attributes}, context);
}

void Add(T value,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>
attributes) noexcept
{
this->Add(value, nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()});
auto context = opentelemetry::context::Context{};
this->Add(value,
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()},
context);
}

void Add(T value,
std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
const opentelemetry::context::Context &context) noexcept
{
this->Add(value,
nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
attributes.begin(), attributes.end()},
context);
}
};

Expand Down
31 changes: 31 additions & 0 deletions api/test/metrics/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
load("//bazel:otel_cc_benchmark.bzl", "otel_cc_benchmark")

cc_test(
name = "noop_sync_instrument_test",
srcs = [
"noop_sync_instrument_test.cc",
],
tags = [
"metrics",
"test",
],
deps = [
"//api",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "meter_provider_test",
srcs = [
"meter_provider_test.cc",
],
tags = [
"metrics",
"test",
],
deps = [
"//api",
"@com_google_googletest//:gtest_main",
],
)
13 changes: 10 additions & 3 deletions api/test/metrics/noop_sync_instrument_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ TEST(Counter, Add)

std::map<std::string, std::string> labels = {{"k1", "v1"}};
EXPECT_NO_THROW(counter->Add(10l, labels));
EXPECT_NO_THROW(counter->Add(10l, labels, opentelemetry::context::Context{}));
EXPECT_NO_THROW(counter->Add(2l));
EXPECT_NO_THROW(counter->Add(2l, opentelemetry::context::Context{}));
EXPECT_NO_THROW(counter->Add(10l, {{"k1", "1"}, {"k2", 2}}));
EXPECT_NO_THROW(counter->Add(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}));
}

TEST(histogram, Record)
Expand All @@ -24,9 +27,10 @@ TEST(histogram, Record)
new opentelemetry::metrics::NoopHistogram<long>("test", "none", "unitless")};

std::map<std::string, std::string> labels = {{"k1", "v1"}};
EXPECT_NO_THROW(counter->Record(10l, labels));
EXPECT_NO_THROW(counter->Record(2l));
EXPECT_NO_THROW(counter->Record(10l, {{"k1", "1"}, {"k2", 2}}));
EXPECT_NO_THROW(counter->Record(10l, labels, opentelemetry::context::Context{}));
EXPECT_NO_THROW(counter->Record(2l, opentelemetry::context::Context{}));
EXPECT_NO_THROW(
counter->Record(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}));
}

TEST(UpDownCountr, Record)
Expand All @@ -36,8 +40,11 @@ TEST(UpDownCountr, Record)

std::map<std::string, std::string> labels = {{"k1", "v1"}};
EXPECT_NO_THROW(counter->Add(10l, labels));
EXPECT_NO_THROW(counter->Add(10l, labels, opentelemetry::context::Context{}));
EXPECT_NO_THROW(counter->Add(2l));
EXPECT_NO_THROW(counter->Add(2l, opentelemetry::context::Context{}));
EXPECT_NO_THROW(counter->Add(10l, {{"k1", "1"}, {"k2", 2}}));
EXPECT_NO_THROW(counter->Add(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}));
}

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once
#ifndef ENABLE_METRICS_PREVIEW
# include "opentelemetry/sdk/metrics/exemplar/filter.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace metrics
{

class AlwaysSampleFilter final : public ExemplarFilter
{
public:
static nostd::shared_ptr<ExemplarFilter> GetAlwaysSampleFilter()
{
static nostd::shared_ptr<ExemplarFilter> alwaysSampleFilter{new AlwaysSampleFilter{}};
return alwaysSampleFilter;
}

bool ShouldSampleMeasurement(long value,
const MetricAttributes &attributes,
const opentelemetry::context::Context &context) noexcept override
{
return true;
}

bool ShouldSampleMeasurement(double value,
const MetricAttributes &attributes,
const opentelemetry::context::Context &context) noexcept override
{
return true;
}

private:
explicit AlwaysSampleFilter() = default;
};
} // namespace metrics
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
#endif
45 changes: 45 additions & 0 deletions sdk/include/opentelemetry/sdk/metrics/exemplar/data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once
#ifndef ENABLE_METRICS_PREVIEW
# include "opentelemetry/common/timestamp.h"
# include "opentelemetry/context/context.h"
# include "opentelemetry/sdk/common/attribute_utils.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace metrics
{
using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap;
/**
* A sample input measurement.
*
* Exemplars also hold information about the environment when the measurement was recorded, for
* example the span and trace ID of the active span when the exemplar was recorded.
*/
class ExemplarData
{
public:
/**
* The set of key/value pairs that were filtered out by the aggregator, but recorded alongside the
* original measurement. Only key/value pairs that were filtered out by the aggregator should be
* included
*/
MetricAttributes GetFilteredAttributes();

/** Returns the timestamp in nanos when measurement was collected. */
opentelemetry::common::SystemTimestamp GetEpochNanos();

/**
* Returns the SpanContext associated with this exemplar. If the exemplar was not recorded
* inside a sampled trace, the Context will be invalid.
*/
opentelemetry::context::Context GetSpanContext();
};

} // namespace metrics
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
#endif
Loading

1 comment on commit 3c7b44b

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'OpenTelemetry-cpp api Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 3c7b44b Previous: 0c9aece Ratio
BM_SpanIdDefaultConstructor 3.426375737434173 ns/iter 1.691003858936915 ns/iter 2.03
BM_SpanIdConstructor 3.4240486161623362 ns/iter 1.6991686811231534 ns/iter 2.02

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.