Skip to content

Commit 555b5f8

Browse files
committed
simplify test and send metrics in app-closing
1 parent 2f4dd5f commit 555b5f8

File tree

2 files changed

+165
-91
lines changed

2 files changed

+165
-91
lines changed

src/datadog/telemetry/telemetry_impl.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,8 +406,9 @@ std::string Telemetry::app_closing() {
406406
});
407407
batch_payloads.emplace_back(std::move(app_closing));
408408

409-
auto metrics = nlohmann::json::array();
410-
409+
nlohmann::json::array_t metrics = nlohmann::json::array();
410+
encode_metrics(metrics, counters_snapshot_);
411+
encode_metrics(metrics, rates_snapshot_);
411412
if (!metrics.empty()) {
412413
auto generate_metrics = nlohmann::json::object({
413414
{"request_type", "generate-metrics"},
@@ -418,6 +419,20 @@ std::string Telemetry::app_closing() {
418419
batch_payloads.emplace_back(std::move(generate_metrics));
419420
}
420421

422+
if (auto distributions_series = encode_distributions(distributions_);
423+
!distributions_.empty()) {
424+
auto distributions_json = nlohmann::json{
425+
{"request_type", "distributions"},
426+
{
427+
"payload",
428+
nlohmann::json{
429+
{"series", distributions_series},
430+
},
431+
},
432+
};
433+
batch_payloads.emplace_back(std::move(distributions_json));
434+
}
435+
421436
if (!logs_.empty()) {
422437
auto encoded_logs = nlohmann::json::array();
423438
for (const auto& log : logs_) {

test/telemetry/test_telemetry.cpp

Lines changed: 148 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -364,34 +364,32 @@ TELEMETRY_IMPLEMENTATION_TEST("Tracer telemetry API") {
364364
auto series = payload["series"];
365365
REQUIRE(series.size() == 2);
366366

367-
for (const auto& s : series) {
368-
CHECK(s["metric"] == "my_counter");
369-
CHECK(s["type"] == "count");
370-
CHECK(s["common"] == true);
371-
CHECK(s["namespace"] == "counter-test");
372-
if (s.contains("tags")) {
373-
REQUIRE(s["tags"].size() == 1);
374-
CHECK(s["tags"][0] == "event:test");
375-
376-
auto points = s["points"];
377-
REQUIRE(points.size() == 1);
378-
379-
CHECK(points[0][0] == mock_time);
380-
CHECK(points[0][1] == 99);
381-
} else {
382-
auto points = s["points"];
383-
REQUIRE(points.size() == 3);
384-
385-
CHECK(points[0][0] == mock_time);
386-
CHECK(points[0][1] == 2);
387-
388-
CHECK(points[1][0] == mock_time);
389-
CHECK(points[1][1] == 1);
390-
391-
CHECK(points[2][0] == mock_time);
392-
CHECK(points[2][1] == 42);
393-
}
394-
}
367+
const auto expected_metrics = nlohmann::json::parse(R"(
368+
[
369+
{
370+
"common": true,
371+
"metric": "my_counter",
372+
"namespace": "counter-test",
373+
"points": [
374+
[ 1672484400, 99 ]
375+
],
376+
"tags": [ "event:test" ],
377+
"type": "count"
378+
},
379+
{
380+
"common": true,
381+
"metric": "my_counter",
382+
"namespace": "counter-test",
383+
"points": [
384+
[ 1672484400, 2 ],
385+
[ 1672484400, 1 ],
386+
[ 1672484400, 42 ]
387+
],
388+
"type": "count"
389+
}
390+
]
391+
)");
392+
CHECK(series == expected_metrics);
395393

396394
// Make sure the next heartbeat doesn't contains counters if no
397395
// datapoint has been incremented, decremented or set.
@@ -435,31 +433,31 @@ TELEMETRY_IMPLEMENTATION_TEST("Tracer telemetry API") {
435433
auto series = payload["series"];
436434
REQUIRE(series.size() == 2);
437435

438-
for (const auto& s : series) {
439-
CHECK(s["metric"] == "request");
440-
CHECK(s["type"] == "rate");
441-
CHECK(s["common"] == true);
442-
CHECK(s["namespace"] == "rate-test");
443-
if (s.contains("tags")) {
444-
REQUIRE(s["tags"].size() == 1);
445-
CHECK(s["tags"][0] == "status:2xx");
446-
447-
auto points = s["points"];
448-
REQUIRE(points.size() == 1);
449-
450-
CHECK(points[0][0] == mock_time);
451-
CHECK(points[0][1] == 5000);
452-
} else {
453-
auto points = s["points"];
454-
REQUIRE(points.size() == 2);
455-
456-
CHECK(points[0][0] == mock_time);
457-
CHECK(points[0][1] == 1000);
458-
459-
CHECK(points[1][0] == mock_time);
460-
CHECK(points[1][1] == 5000);
461-
}
462-
}
436+
const auto expected_metrics = nlohmann::json::parse(R"(
437+
[
438+
{
439+
"common": true,
440+
"metric": "request",
441+
"namespace": "rate-test",
442+
"points": [
443+
[ 1672484400, 5000 ]
444+
],
445+
"tags": [ "status:2xx" ],
446+
"type": "rate"
447+
},
448+
{
449+
"common": true,
450+
"metric": "request",
451+
"namespace": "rate-test",
452+
"points": [
453+
[ 1672484400, 1000 ],
454+
[ 1672484400, 5000 ]
455+
],
456+
"type": "rate"
457+
}
458+
]
459+
)");
460+
CHECK(series == expected_metrics);
463461

464462
// Make sure the next heartbeat doesn't contains distributions if no
465463
// datapoint has been added to a distribution.
@@ -506,43 +504,29 @@ TELEMETRY_IMPLEMENTATION_TEST("Tracer telemetry API") {
506504
auto distribution_series = distribution_message["payload"]["series"];
507505
REQUIRE(distribution_series.size() == 3);
508506

509-
for (auto& dist : distribution_series) {
510-
if (dist["metric"] == "response_time") {
511-
CHECK(dist["common"] == false);
512-
CHECK(dist["namespace"] == "dist-test");
513-
if (dist.contains("tags")) {
514-
const std::vector<std::string> expected_tags{"status:200",
515-
"method:GET"};
516-
CHECK(dist["tags"] == expected_tags);
517-
518-
auto datapoint = dist["points"];
519-
REQUIRE(datapoint.size() == 1);
520-
521-
const std::vector<uint64_t> expected_points{6530};
522-
CHECK(expected_points == datapoint);
523-
} else {
524-
auto datapoint = dist["points"];
525-
REQUIRE(datapoint.size() == 3);
526-
527-
const std::vector<uint64_t> expected_points{128, 42, 3000};
528-
CHECK(expected_points == datapoint);
529-
}
530-
} else if (dist["metric"] == "request_size") {
531-
CHECK(dist["common"] == true);
532-
CHECK(dist["namespace"] == "dist-test-2");
533-
534-
auto datapoint = dist["points"];
535-
REQUIRE(datapoint.size() == 2);
536-
537-
const std::vector<uint64_t> expected_points{1843, 4135};
538-
CHECK(expected_points == datapoint);
539-
} else {
540-
FAIL(
541-
"expected distribution name {response_time, request_size} but "
542-
"got "
543-
<< dist["metric"]);
507+
const auto expected_series = nlohmann::json::parse(R"([
508+
{
509+
"common":false,
510+
"metric":"response_time",
511+
"namespace":"dist-test",
512+
"points": [6530],
513+
"tags":["status:200","method:GET"]
514+
},
515+
{
516+
"common":true,
517+
"metric": "request_size",
518+
"namespace":"dist-test-2",
519+
"points":[1843,4135]
520+
},
521+
{
522+
"common": false,
523+
"metric":"response_time",
524+
"namespace":"dist-test",
525+
"points":[128,42,3000]
544526
}
545-
}
527+
])");
528+
529+
CHECK(distribution_series == expected_series);
546530

547531
// Make sure the next heartbeat doesn't contains distributions if no
548532
// datapoint has been added to a distribution.
@@ -557,6 +541,81 @@ TELEMETRY_IMPLEMENTATION_TEST("Tracer telemetry API") {
557541
CHECK(payload["request_type"] == "app-heartbeat");
558542
}
559543

544+
SECTION("dtor sends metrics and distributions") {
545+
// metrics captured before the aggregation task
546+
const Clock clock = [] {
547+
TimePoint result;
548+
result.wall = std::chrono::system_clock::from_time_t(1744706125);
549+
return result;
550+
};
551+
const Distribution response_time{"response_time", "dist-test", false};
552+
const Rate rps{"request", "rate-test", true};
553+
const Counter my_counter{"my_counter", "counter-test", true};
554+
{
555+
Telemetry telemetry{*finalize_config(), logger, client,
556+
scheduler, *url, clock};
557+
telemetry.increment_counter(my_counter); // = 1
558+
telemetry.add_datapoint(response_time, 128);
559+
telemetry.set_rate(rps, 1000);
560+
client->clear();
561+
}
562+
563+
// Expect 2 metrics with 1 datapoint each and 1 ditribution
564+
auto message_batch = nlohmann::json::parse(client->request_body);
565+
REQUIRE(is_valid_telemetry_payload(message_batch) == true);
566+
REQUIRE(message_batch["payload"].size() == 3);
567+
568+
for (const auto& payload : message_batch["payload"]) {
569+
const auto& req_type = payload["request_type"];
570+
if (req_type == "generate-metrics") {
571+
const auto& metrics_series = payload["payload"]["series"];
572+
REQUIRE(metrics_series.size() == 2);
573+
574+
for (const auto& s : metrics_series) {
575+
if (s["metric"] == "my_counter") {
576+
const auto expected_counter = nlohmann::json::parse(R"(
577+
{
578+
"common":true,
579+
"metric":"my_counter",
580+
"namespace":"counter-test",
581+
"type": "count",
582+
"points": [[1744706125, 1]]
583+
}
584+
)");
585+
CHECK(s == expected_counter);
586+
} else if (s["metric"] == "request") {
587+
const auto expected_rate = nlohmann::json::parse(R"(
588+
{
589+
"common":true,
590+
"metric":"request",
591+
"namespace":"rate-test",
592+
"type": "rate",
593+
"points": [[1744706125, 1000]]
594+
}
595+
)");
596+
CHECK(s == expected_rate);
597+
} else {
598+
FAIL("unexpected metrics name, got " << s["metric"]);
599+
}
600+
}
601+
} else if (req_type == "distributions") {
602+
const auto& distribution_series = payload["payload"]["series"];
603+
REQUIRE(distribution_series.size() == 1);
604+
605+
const auto& d0 = distribution_series[0];
606+
const auto expected_d0 = nlohmann::json::parse(R"(
607+
{
608+
"common":false,
609+
"metric":"response_time",
610+
"namespace":"dist-test",
611+
"points": [128]
612+
}
613+
)");
614+
CHECK(d0 == expected_d0);
615+
}
616+
}
617+
}
618+
560619
SECTION("logs serialization") {
561620
SECTION("log level is correct") {
562621
struct TestCase {

0 commit comments

Comments
 (0)