Skip to content

Commit

Permalink
agents: use OTLP Summary for percentile metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
santigimeno committed Sep 12, 2024
1 parent 09cf939 commit f0da982
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 8 deletions.
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
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

0 comments on commit f0da982

Please sign in to comment.