Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
60 changes: 60 additions & 0 deletions agents/otlp/src/otlp_common.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "otlp_common.h"
// NOLINTNEXTLINE(build/c++11)
#include <chrono>
#include <unordered_map>
#include "asserts-cpp/asserts.h"
#include "env-inl.h"
#include "nlohmann/json.hpp"
Expand Down Expand Up @@ -104,6 +105,28 @@ static void add_gauge(std::vector<MetricData>& metrics,
metrics.push_back(metric_data);
}

// NOLINTNEXTLINE(runtime/references)
static void add_summary(std::vector<MetricData>& metrics,
const time_point& start,
const time_point& end,
const char* name,
const char* unit,
InstrumentValueType type,
std::unordered_map<double, ValueType>&& values,
PointAttributes attrs = {}) {
opentelemetry::sdk::metrics::SummaryPointData summary_point_data{};
summary_point_data.quantile_values_ = std::move(values);
MetricData metric_data{
InstrumentDescriptor{
name, "", unit, InstrumentType::kSummary, type },
AggregationTemporality::kUnspecified,
SystemTimestamp{ start },
SystemTimestamp{ end },
std::vector<PointDataAttributes>{{ attrs, summary_point_data }}
};
metrics.push_back(metric_data);
}

InstrumentationScope* GetScope() {
static std::unique_ptr<InstrumentationScope> scope =
InstrumentationScope::Create("nsolid", NODE_VERSION "+ns" NSOLID_VERSION);
Expand Down Expand Up @@ -255,6 +278,43 @@ void fill_env_metrics(std::vector<MetricData>& metrics,
}
NSOLID_ENV_METRICS_NUMBERS(V)
#undef V

// Add the summary metrics separately.
add_summary(metrics,
process_start,
end,
"gc_dur",
kNSUSecs,
InstrumentValueType::kDouble,
{{ 0.5, stor.gc_dur_us_median },
{ 0.99, stor.gc_dur_us99_ptile }},
attrs);
add_summary(metrics,
process_start,
end,
"dns",
kNSMSecs,
InstrumentValueType::kDouble,
{{ 0.5, stor.dns_median }, { 0.99, stor.dns99_ptile }},
attrs);
add_summary(metrics,
process_start,
end,
"http_client",
kNSMSecs,
InstrumentValueType::kDouble,
{{ 0.5, stor.http_client99_ptile },
{ 0.99, stor.http_client_median }},
attrs);
add_summary(metrics,
process_start,
end,
"http_server",
kNSMSecs,
InstrumentValueType::kDouble,
{{ 0.5, stor.http_server_median },
{ 0.99, stor.http_server99_ptile }},
attrs);
}

void fill_log_recordable(LogsRecordable* recordable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class OtlpMetricUtils
static void ConvertGaugeMetric(const opentelemetry::sdk::metrics::MetricData &metric_data,
proto::metrics::v1::Gauge *const gauge) noexcept;

static void ConvertSummaryMetric(const opentelemetry::sdk::metrics::MetricData &metric_data,
proto::metrics::v1::Summary *const summary) noexcept;

static void PopulateInstrumentInfoMetrics(
const opentelemetry::sdk::metrics::MetricData &metric_data,
proto::metrics::v1::Metric *metric) noexcept;
Expand Down
63 changes: 63 additions & 0 deletions deps/opentelemetry-cpp/exporters/otlp/src/otlp_metric_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ metric_sdk::AggregationType OtlpMetricUtils::GetAggregationType(
{
return metric_sdk::AggregationType::kLastValue;
}
else if (nostd::holds_alternative<sdk::metrics::SummaryPointData>(
point_data_with_attributes.point_data))
{
return metric_sdk::AggregationType::kSummary;
}
return metric_sdk::AggregationType::kDrop;
}

Expand Down Expand Up @@ -185,6 +190,56 @@ void OtlpMetricUtils::ConvertGaugeMetric(const opentelemetry::sdk::metrics::Metr
}
}

void OtlpMetricUtils::ConvertSummaryMetric(const metric_sdk::MetricData &metric_data,
proto::metrics::v1::Summary *const summary) noexcept
{
auto start_ts = metric_data.start_ts.time_since_epoch().count();
auto ts = metric_data.end_ts.time_since_epoch().count();
for (auto &point_data_with_attributes : metric_data.point_data_attr_)
{
proto::metrics::v1::SummaryDataPoint *proto_summary_point_data = summary->add_data_points();
proto_summary_point_data->set_start_time_unix_nano(start_ts);
proto_summary_point_data->set_time_unix_nano(ts);
auto summary_data = nostd::get<sdk::metrics::SummaryPointData>(point_data_with_attributes.point_data);

// sum
if ((nostd::holds_alternative<int64_t>(summary_data.sum_)))
{
// Use static_cast to avoid C4244 in MSVC
proto_summary_point_data->set_sum(
static_cast<double>(nostd::get<int64_t>(summary_data.sum_)));
}
else
{
proto_summary_point_data->set_sum(nostd::get<double>(summary_data.sum_));
}
// count
proto_summary_point_data->set_count(summary_data.count_);
// quantile values
for (auto &kv : summary_data.quantile_values_)
{
proto::metrics::v1::SummaryDataPoint::ValueAtQuantile *quantile =
proto_summary_point_data->add_quantile_values();
quantile->set_quantile(kv.first);
if ((nostd::holds_alternative<int64_t>(kv.second)))
{
// Use static_cast to avoid C4244 in MSVC
quantile->set_value(static_cast<double>(nostd::get<int64_t>(kv.second)));
}
else
{
quantile->set_value(nostd::get<double>(kv.second));
}
}
// set attributes
for (auto &kv_attr : point_data_with_attributes.attributes)
{
OtlpPopulateAttributeUtils::PopulateAttribute(proto_summary_point_data->add_attributes(),
kv_attr.first, kv_attr.second);
}
}
}

void OtlpMetricUtils::PopulateInstrumentInfoMetrics(
const opentelemetry::sdk::metrics::MetricData &metric_data,
proto::metrics::v1::Metric *metric) noexcept
Expand All @@ -207,6 +262,10 @@ void OtlpMetricUtils::PopulateInstrumentInfoMetrics(
ConvertGaugeMetric(metric_data, metric->mutable_gauge());
break;
}
case metric_sdk::AggregationType::kSummary: {
ConvertSummaryMetric(metric_data, metric->mutable_summary());
break;
}
default:
break;
}
Expand Down Expand Up @@ -278,6 +337,8 @@ sdk::metrics::AggregationTemporality OtlpMetricUtils::DeltaTemporalitySelector(
case sdk::metrics::InstrumentType::kUpDownCounter:
case sdk::metrics::InstrumentType::kObservableUpDownCounter:
return sdk::metrics::AggregationTemporality::kCumulative;
case sdk::metrics::InstrumentType::kSummary:
return sdk::metrics::AggregationTemporality::kUnspecified;
}
return sdk::metrics::AggregationTemporality::kUnspecified;
}
Expand All @@ -301,6 +362,8 @@ sdk::metrics::AggregationTemporality OtlpMetricUtils::LowMemoryTemporalitySelect
case sdk::metrics::InstrumentType::kUpDownCounter:
case sdk::metrics::InstrumentType::kObservableUpDownCounter:
return sdk::metrics::AggregationTemporality::kCumulative;
case sdk::metrics::InstrumentType::kSummary:
return sdk::metrics::AggregationTemporality::kUnspecified;
}
return sdk::metrics::AggregationTemporality::kUnspecified;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ class DefaultAggregation
return AggregationType::kHistogram;
case InstrumentType::kObservableGauge:
return AggregationType::kLastValue;
case InstrumentType::kSummary:
return AggregationType::kSummary;
default:
return AggregationType::kDrop;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace metrics

using PointAttributes = opentelemetry::sdk::common::OrderedAttributeMap;
using PointType = opentelemetry::nostd::
variant<SumPointData, HistogramPointData, LastValuePointData, DropPointData>;
variant<SumPointData, HistogramPointData, LastValuePointData, DropPointData, SummaryPointData>;

struct PointDataAttributes
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@ class DropPointData
DropPointData &operator=(DropPointData &&) = default;
};

class SummaryPointData
{
public:
// TODO: remove ctors and initializers when GCC<5 stops shipping on Ubuntu
SummaryPointData(SummaryPointData &&) = default;
SummaryPointData(const SummaryPointData &) = default;
SummaryPointData &operator=(SummaryPointData &&) = default;
SummaryPointData() = default;

uint64_t count_ = {};
ValueType sum_ = {};
std::unordered_map<double, ValueType> quantile_values_ = {};
};

} // namespace metrics
} // namespace sdk
OPENTELEMETRY_END_NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ enum class InstrumentType
kUpDownCounter,
kObservableCounter,
kObservableGauge,
kObservableUpDownCounter
kObservableUpDownCounter,
kSummary
};

enum class InstrumentClass
Expand All @@ -44,6 +45,7 @@ enum class AggregationType
kHistogram,
kLastValue,
kSum,
kSummary,
kDefault
};

Expand Down
25 changes: 21 additions & 4 deletions test/agents/test-otlp-grpc-metrics.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ if (process.argv[2] === 'child') {
['loop_avg_tasks', undefined, 'asDouble', 'gauge'],
['loop_estimated_lag', 'ms', 'asDouble', 'gauge'],
['loop_idle_percent', undefined, 'asDouble', 'gauge'],
['gc_dur', 'us', 'asDouble', 'summary'],
['dns', 'ms', 'asDouble', 'summary'],
['http_client', 'ms', 'asDouble', 'summary'],
['http_server', 'ms', 'asDouble', 'summary'],
];

// The format of the metrics is as follows:
Expand Down Expand Up @@ -490,10 +494,23 @@ if (process.argv[2] === 'child') {
const time = BigInt(dataPoint.timeUnixNano);
assert.ok(time);
assert.ok(time > startTime);
if (type === 'asInt') {
validateNumber(parseInt(dataPoint[type], 10), `${name}.${type}`);
} else { // asDouble
validateNumber(dataPoint[type], `${name}.${type}`);
if (aggregation !== 'summary') {
if (type === 'asInt') {
validateNumber(parseInt(dataPoint[type], 10), `${name}.${type}`);
} else { // asDouble
validateNumber(dataPoint[type], `${name}.${type}`);
}
} else {
validateArray(dataPoint.quantileValues, `${name}.quantileValues`);
assert.strictEqual(dataPoint.quantileValues.length, 2);
assert.strictEqual(dataPoint.quantileValues[0].quantile, 0.99);
assert.strictEqual(dataPoint.quantileValues[1].quantile, 0.5);
if (dataPoint.quantileValues[0].value) {
validateNumber(dataPoint.quantileValues[0].value, `${name}.quantileValues[0].value`);
}
if (dataPoint.quantileValues[1].value) {
validateNumber(dataPoint.quantileValues[1].value, `${name}.quantileValues[1].value`);
}
}

expected.splice(expectedIndex, 1);
Expand Down
25 changes: 21 additions & 4 deletions test/agents/test-otlp-metrics.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ if (process.argv[2] === 'child') {
['loop_avg_tasks', undefined, 'asDouble', 'gauge'],
['loop_estimated_lag', 'ms', 'asDouble', 'gauge'],
['loop_idle_percent', undefined, 'asDouble', 'gauge'],
['gc_dur', 'us', 'asDouble', 'summary'],
['dns', 'ms', 'asDouble', 'summary'],
['http_client', 'ms', 'asDouble', 'summary'],
['http_server', 'ms', 'asDouble', 'summary'],
];

// The format of the metrics is as follows:
Expand Down Expand Up @@ -490,10 +494,23 @@ if (process.argv[2] === 'child') {
const time = BigInt(dataPoint.timeUnixNano);
assert.ok(time);
assert.ok(time > startTime);
if (type === 'asInt') {
validateNumber(parseInt(dataPoint[type], 10), `${name}.${type}`);
} else { // asDouble
validateNumber(dataPoint[type], `${name}.${type}`);
if (aggregation !== 'summary') {
if (type === 'asInt') {
validateNumber(parseInt(dataPoint[type], 10), `${name}.${type}`);
} else { // asDouble
validateNumber(dataPoint[type], `${name}.${type}`);
}
} else {
validateArray(dataPoint.quantileValues, `${name}.quantileValues`);
assert.strictEqual(dataPoint.quantileValues.length, 2);
assert.strictEqual(dataPoint.quantileValues[0].quantile, 0.99);
assert.strictEqual(dataPoint.quantileValues[1].quantile, 0.5);
if (dataPoint.quantileValues[0].value) {
validateNumber(dataPoint.quantileValues[0].value, `${name}.quantileValues[0].value`);
}
if (dataPoint.quantileValues[1].value) {
validateNumber(dataPoint.quantileValues[1].value, `${name}.quantileValues[1].value`);
}
}

expected.splice(expectedIndex, 1);
Expand Down