Skip to content

Commit d09ef1c

Browse files
authored
Add TraceId class. (open-telemetry#31)
1 parent ffd22ab commit d09ef1c

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Copyright 2020, OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include <cstdint>
18+
#include <cstring>
19+
20+
#include "opentelemetry/nostd/span.h"
21+
22+
namespace opentelemetry
23+
{
24+
namespace trace
25+
{
26+
27+
// TraceId represents an opaque 128-bit trace identifier. The trace identifier
28+
// remains constant across the trace. A valid trace identifier is a 16-byte array with at
29+
// least one non-zero byte.
30+
class TraceId final
31+
{
32+
public:
33+
// The size in bytes of the TraceId.
34+
static constexpr int kSize = 16;
35+
36+
// An invalid TraceId (all zeros).
37+
TraceId() noexcept : rep_{0} {}
38+
39+
// Creates a TraceId with the given ID.
40+
explicit TraceId(nostd::span<const uint8_t, kSize> id) noexcept
41+
{
42+
memcpy(rep_, id.data(), kSize);
43+
}
44+
45+
// Populates the buffer with the lowercase base16 representation of the ID.
46+
void ToLowerBase16(nostd::span<char, 2 * kSize> buffer) const noexcept
47+
{
48+
constexpr char kHex[] = "0123456789ABCDEF";
49+
for (int i = 0; i < kSize; ++i)
50+
{
51+
buffer[i * 2 + 0] = kHex[(rep_[i] >> 4) & 0xF];
52+
buffer[i * 2 + 1] = kHex[(rep_[i] >> 0) & 0xF];
53+
}
54+
}
55+
56+
// Returns a nostd::span of the ID.
57+
nostd::span<const uint8_t, kSize> Id() const noexcept
58+
{
59+
return nostd::span<const uint8_t, kSize>(rep_);
60+
}
61+
62+
bool operator==(const TraceId &that) const noexcept
63+
{
64+
return memcmp(rep_, that.rep_, kSize) == 0;
65+
}
66+
67+
bool operator!=(const TraceId &that) const noexcept { return !(*this == that); }
68+
69+
// Returns false if the TraceId is all zeros.
70+
bool IsValid() const noexcept { return *this != TraceId(); }
71+
72+
// Copies the opaque TraceId data to dest.
73+
void CopyBytesTo(nostd::span<uint8_t, kSize> dest) const noexcept
74+
{
75+
memcpy(dest.data(), rep_, kSize);
76+
}
77+
78+
private:
79+
uint8_t rep_[kSize];
80+
};
81+
82+
} // namespace trace
83+
} // namespace opentelemetry

api/test/trace/BUILD

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,14 @@ cc_test(
1919
"@com_google_googletest//:gtest_main",
2020
],
2121
)
22+
23+
cc_test(
24+
name = "trace_id_test",
25+
srcs = [
26+
"trace_id_test.cc",
27+
],
28+
deps = [
29+
"//api",
30+
"@com_google_googletest//:gtest_main",
31+
],
32+
)

api/test/trace/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@ add_executable(span_id_test span_id_test.cc)
99
target_link_libraries(span_id_test ${GTEST_BOTH_LIBRARIES}
1010
${CMAKE_THREAD_LIBS_INIT} opentelemetry_api)
1111
gtest_add_tests(TARGET span_id_test TEST_PREFIX trace. TEST_LIST span_id_test)
12+
13+
add_executable(trace_id_test trace_id_test.cc)
14+
target_link_libraries(trace_id_test ${GTEST_BOTH_LIBRARIES}
15+
${CMAKE_THREAD_LIBS_INIT} opentelemetry_api)
16+
gtest_add_tests(TARGET trace_id_test TEST_PREFIX trace. TEST_LIST trace_id_test)

api/test/trace/trace_id_test.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "opentelemetry/trace/trace_id.h"
2+
3+
#include <cstring>
4+
#include <string>
5+
6+
#include <gtest/gtest.h>
7+
8+
namespace
9+
{
10+
11+
using opentelemetry::trace::TraceId;
12+
13+
std::string Hex(const opentelemetry::trace::TraceId &trace)
14+
{
15+
char buf[32];
16+
trace.ToLowerBase16(buf);
17+
return std::string(buf, sizeof(buf));
18+
}
19+
20+
TEST(TraceIdTest, DefaultConstruction)
21+
{
22+
TraceId id;
23+
EXPECT_FALSE(id.IsValid());
24+
EXPECT_EQ("00000000000000000000000000000000", Hex(id));
25+
}
26+
27+
TEST(TraceIdTest, ValidId)
28+
{
29+
constexpr uint8_t buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1};
30+
TraceId id(buf);
31+
EXPECT_TRUE(id.IsValid());
32+
EXPECT_EQ("01020304050607080807060504030201", Hex(id));
33+
EXPECT_NE(TraceId(), id);
34+
EXPECT_EQ(TraceId(buf), id);
35+
}
36+
37+
TEST(TraceIdTest, CopyBytesTo)
38+
{
39+
constexpr uint8_t src[] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 3, 2, 1};
40+
TraceId id(src);
41+
uint8_t buf[TraceId::kSize];
42+
id.CopyBytesTo(buf);
43+
EXPECT_TRUE(memcmp(src, buf, sizeof(buf)) == 0);
44+
}
45+
} // namespace

0 commit comments

Comments
 (0)