Program Listing for File reservoir_cell.h
↰ Return to documentation for file (/home/docs/checkouts/readthedocs.org/user_builds/opentelemetry-cpp/checkouts/latest/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h
)
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <cstddef>
#include <memory>
#include "opentelemetry/common/timestamp.h"
#include "opentelemetry/nostd/variant.h"
#include "opentelemetry/sdk/metrics/data/exemplar_data.h"
#include "opentelemetry/sdk/metrics/exemplar/filter.h"
#include "opentelemetry/trace/context.h"
#include "opentelemetry/version.h"
OPENTELEMETRY_BEGIN_NAMESPACE
namespace context
{
class Context;
} // namespace context
namespace sdk
{
namespace metrics
{
class ReservoirCell
{
public:
ReservoirCell() = default;
void RecordLongMeasurement(int64_t value,
const MetricAttributes &attributes,
const opentelemetry::context::Context &context)
{
value_ = value;
offerMeasurement(attributes, context);
}
void RecordDoubleMeasurement(double value,
const MetricAttributes &attributes,
const opentelemetry::context::Context &context)
{
value_ = value;
offerMeasurement(attributes, context);
}
std::shared_ptr<ExemplarData> GetAndResetLong(const MetricAttributes &point_attributes)
{
if (!context_)
{
return nullptr;
}
auto attributes = attributes_;
PointDataAttributes point_data_attributes;
point_data_attributes.attributes = filtered(attributes, point_attributes);
if (nostd::holds_alternative<int64_t>(value_))
{
point_data_attributes.point_data =
ExemplarData::CreateSumPointData(nostd::get<int64_t>(value_));
}
std::shared_ptr<ExemplarData> result{
new ExemplarData{ExemplarData::Create(context_, record_time_, point_data_attributes)}};
reset();
return result;
}
std::shared_ptr<ExemplarData> GetAndResetDouble(const MetricAttributes &point_attributes)
{
if (!context_)
{
return nullptr;
}
auto attributes = attributes_;
PointDataAttributes point_data_attributes;
point_data_attributes.attributes = filtered(attributes, point_attributes);
if (nostd::holds_alternative<double>(value_))
{
point_data_attributes.point_data =
ExemplarData::CreateSumPointData(nostd::get<double>(value_));
}
std::shared_ptr<ExemplarData> result{
new ExemplarData{ExemplarData::Create(context_, record_time_, point_data_attributes)}};
reset();
return result;
}
void reset()
{
value_ = 0.0;
record_time_ = opentelemetry::common::SystemTimestamp{};
}
private:
static MetricAttributes filtered(const MetricAttributes &original,
const MetricAttributes &metric_point)
{
auto res = original;
for (const auto &kv : metric_point)
{
auto it = res.find(kv.first);
if (it != res.end())
{
res.erase(it);
}
}
return res;
}
void offerMeasurement(const MetricAttributes &attributes,
const opentelemetry::context::Context &context)
{
attributes_ = attributes;
record_time_ = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now());
auto span = opentelemetry::trace::GetSpan(context);
if (span)
{
auto current_ctx = span->GetContext();
if (current_ctx.IsValid())
{
context_.reset(new trace::SpanContext{current_ctx});
}
}
}
// Cell stores either long or double values, but must not store both
std::shared_ptr<trace::SpanContext> context_;
nostd::variant<int64_t, double> value_;
opentelemetry::common::SystemTimestamp record_time_;
MetricAttributes attributes_;
// For testing
friend class ReservoirCellTestPeer;
};
} // namespace metrics
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE