Skip to content

Commit bb3d458

Browse files
Rename container::find_docker_container_id to container::find_container_id and update its implementation so that it is regex-based and covers the same set of inputs as other tracers, like Java and .NET -- the implementation is borrowed from the Java tracer
1 parent edb4f89 commit bb3d458

File tree

3 files changed

+65
-18
lines changed

3 files changed

+65
-18
lines changed

src/datadog/platform_util.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include <cstdint>
44
#include <fstream>
5+
#include <cassert>
6+
#include <regex>
57

68
// clang-format off
79
#if defined(__x86_64__) || defined(_M_X64)
@@ -338,31 +340,33 @@ Optional<Cgroup> get_cgroup_version() {
338340
return nullopt;
339341
}
340342

341-
Optional<std::string> find_docker_container_id_from_cgroup() {
343+
Optional<std::string> find_container_id_from_cgroup() {
342344
auto cgroup_fd = std::ifstream("/proc/self/cgroup", std::ios::in);
343345
if (!cgroup_fd.is_open()) return nullopt;
344346

345-
return find_docker_container_id(cgroup_fd);
347+
return find_container_id(cgroup_fd);
346348
}
347349
#endif
348350
} // namespace
349351

350-
Optional<std::string> find_docker_container_id(std::istream& source) {
351-
constexpr std::string_view docker_str = "docker-";
352+
Optional<std::string> find_container_id(std::istream& source) {
353+
static const std::string uuid_regex_str = "[0-9a-f]{8}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{4}[-_][0-9a-f]{12}|(?:[0-9a-f]{8}(?:-[0-9a-f]{4}){4}$)";
354+
static const std::string container_regex_str = "[0-9a-f]{64}";
355+
static const std::string task_regex_str = "[0-9a-f]{32}-\\d+";
356+
static const std::regex path_reg(
357+
"(?:.+)?(" + uuid_regex_str + "|" + container_regex_str + "|" + task_regex_str +
358+
")(?:\\.scope)?$");
352359

353360
std::string line;
354361
while (std::getline(source, line)) {
355362
// Example:
356363
// `0::/system.slice/docker-abcdef0123456789abcdef0123456789.scope`
357-
if (auto beg = line.find(docker_str); beg != std::string::npos) {
358-
beg += docker_str.size();
359-
auto end = line.find(".scope", beg);
360-
if (end == std::string::npos || end - beg <= 0) {
361-
continue;
362-
}
364+
std::smatch match;
365+
if (std::regex_match(line, match, path_reg)) {
366+
assert(match.ready());
367+
assert(match.size() == 2);
363368

364-
auto container_id = line.substr(beg, end - beg);
365-
return container_id;
369+
return match.str(1);
366370
}
367371
}
368372

@@ -382,7 +386,7 @@ Optional<ContainerID> get_id() {
382386
ContainerID id;
383387
switch (*maybe_cgroup) {
384388
case Cgroup::v1: {
385-
if (auto maybe_id = find_docker_container_id_from_cgroup()) {
389+
if (auto maybe_id = find_container_id_from_cgroup()) {
386390
id.value = *maybe_id;
387391
id.type = ContainerID::Type::container_id;
388392
break;

src/datadog/platform_util.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ struct ContainerID final {
8484
std::string value;
8585
};
8686

87-
/// Find the docker container ID from a given source.
87+
/// Find the container ID from a given source.
8888
/// This function is exposed mainly for testing purposes.
8989
///
90-
/// @param source The input from which to read the Docker container ID.
91-
/// @return An Optional containing the Docker container ID if found, otherwise
90+
/// @param source The input from which to read the container ID.
91+
/// @return An Optional containing the container ID if found, otherwise
9292
/// nothing.
93-
Optional<std::string> find_docker_container_id(std::istream& source);
93+
Optional<std::string> find_container_id(std::istream& source);
9494

9595
/// Function to retrieve the container metadata.
9696
///

test/test_platform_util.cpp

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,50 @@ PLATFORM_UTIL_TEST("find docker container ID") {
5656

5757
std::istringstream is(test_case.input);
5858

59-
auto maybe_container_id = container::find_docker_container_id(is);
59+
auto maybe_container_id = container::find_container_id(is);
60+
if (test_case.expected_container_id.has_value()) {
61+
REQUIRE(maybe_container_id.has_value());
62+
CHECK(*maybe_container_id == *test_case.expected_container_id);
63+
} else {
64+
CHECK(!maybe_container_id.has_value());
65+
}
66+
}
67+
68+
PLATFORM_UTIL_TEST("find Fargate 1.3 container ID") {
69+
struct TestCase {
70+
size_t line;
71+
std::string_view name;
72+
std::string input;
73+
Optional<std::string> expected_container_id;
74+
};
75+
76+
auto test_case = GENERATE(values<TestCase>({
77+
{__LINE__, "empty inputs", "", nullopt},
78+
{__LINE__, "no Fargate 1.3 container ID", "coucou", nullopt},
79+
{__LINE__, "one line with Fargate 1.3 container ID",
80+
"1:name=systemd:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da",
81+
"432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da"},
82+
{__LINE__, "multiline with Fargate 1.3 container ID", R"(
83+
11:hugetlb:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
84+
10:pids:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
85+
9:cpuset:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
86+
8:net_cls,net_prio:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
87+
7:cpu,cpuacct:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
88+
6:perf_event:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
89+
5:freezer:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
90+
4:devices:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
91+
3:blkio:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
92+
2:memory:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
93+
1:name=systemd:/ecs/55091c13-b8cf-4801-b527-f4601742204d/432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da
94+
)",
95+
"432624d2150b349fe35ba397284dea788c2bf66b885d14dfc1569b01890ca7da"},
96+
}));
97+
98+
CAPTURE(test_case.name);
99+
100+
std::istringstream is(test_case.input);
101+
102+
auto maybe_container_id = container::find_container_id(is);
60103
if (test_case.expected_container_id.has_value()) {
61104
REQUIRE(maybe_container_id.has_value());
62105
CHECK(*maybe_container_id == *test_case.expected_container_id);

0 commit comments

Comments
 (0)