diff --git a/api/BUILD b/api/BUILD index e2fceae4c1b..957ac227bda 100644 --- a/api/BUILD +++ b/api/BUILD @@ -1,3 +1,17 @@ +# Copyright 2019, OpenTelemetry Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + package(default_visibility = ["//visibility:public"]) cc_library( diff --git a/api/include/opentelemetry/trace/span_id.h b/api/include/opentelemetry/trace/span_id.h new file mode 100644 index 00000000000..74fc7393e69 --- /dev/null +++ b/api/include/opentelemetry/trace/span_id.h @@ -0,0 +1,74 @@ +// Copyright 2019, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include +#include + +#include "opentelemetry/nostd/span.h" + +namespace opentelemetry +{ +namespace trace +{ + +class SpanId final +{ +public: + // The size in bytes of the SpanId. + static constexpr int kSize = 8; + + // An invalid SpanId (all zeros). + SpanId() noexcept : rep_{0} {} + + // Creates a SpanId with the given ID. + explicit SpanId(nostd::span id) noexcept { memcpy(rep_, id.data(), kSize); } + + // Populates the buffer with the lowercase base16 representation of the ID. + void ToLowerBase16(nostd::span buffer) const noexcept + { + constexpr char kHex[] = "0123456789ABCDEF"; + for (int i = 0; i < kSize; ++i) + { + buffer[i * 2 + 0] = kHex[(rep_[i] >> 4) & 0xF]; + buffer[i * 2 + 1] = kHex[(rep_[i] >> 0) & 0xF]; + } + } + + // Returns a nostd::span of the ID. + nostd::span Id() const noexcept + { + return nostd::span(rep_); + } + + bool operator==(const SpanId &that) const noexcept { return memcmp(rep_, that.rep_, kSize) == 0; } + + bool operator!=(const SpanId &that) const noexcept { return !(*this == that); } + + // Returns false if the SpanId is all zeros. + bool IsValid() const noexcept { return *this != SpanId(); } + + // Copies the opaque SpanId data to dest. + void CopyBytesTo(nostd::span dest) const noexcept + { + memcpy(dest.data(), rep_, kSize); + } + +private: + uint8_t rep_[kSize]; +}; + +} // namespace trace +} // namespace opentelemetry diff --git a/api/test/trace/BUILD b/api/test/trace/BUILD index a2228032838..2ea3261c95a 100644 --- a/api/test/trace/BUILD +++ b/api/test/trace/BUILD @@ -8,3 +8,14 @@ cc_test( "@com_google_googletest//:gtest_main", ], ) + +cc_test( + name = "span_id_test", + srcs = [ + "span_id_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/api/test/trace/CMakeLists.txt b/api/test/trace/CMakeLists.txt index 2e8d6bca1fe..7aed0a9197f 100644 --- a/api/test/trace/CMakeLists.txt +++ b/api/test/trace/CMakeLists.txt @@ -4,3 +4,8 @@ add_executable(noop_test noop_test.cc) target_link_libraries(noop_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests(TARGET noop_test TEST_PREFIX trace. TEST_LIST noop_test) + +add_executable(span_id_test span_id_test.cc) +target_link_libraries(span_id_test ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) +gtest_add_tests(TARGET span_id_test TEST_PREFIX trace. TEST_LIST span_id_test) diff --git a/api/test/trace/span_id_test.cc b/api/test/trace/span_id_test.cc new file mode 100644 index 00000000000..c25c086cc50 --- /dev/null +++ b/api/test/trace/span_id_test.cc @@ -0,0 +1,45 @@ +#include "opentelemetry/trace/span_id.h" + +#include +#include + +#include + +namespace +{ + +using opentelemetry::trace::SpanId; + +std::string Hex(const opentelemetry::trace::SpanId &span) +{ + char buf[16]; + span.ToLowerBase16(buf); + return std::string(buf, sizeof(buf)); +} + +TEST(SpanIdTest, DefaultConstruction) +{ + SpanId id; + EXPECT_FALSE(id.IsValid()); + EXPECT_EQ("0000000000000000", Hex(id)); +} + +TEST(SpanIdTest, ValidId) +{ + constexpr uint8_t buf[] = {1, 2, 3, 4, 5, 6, 7, 8}; + SpanId id(buf); + EXPECT_TRUE(id.IsValid()); + EXPECT_EQ("0102030405060708", Hex(id)); + EXPECT_NE(SpanId(), id); + EXPECT_EQ(SpanId(buf), id); +} + +TEST(SpanIdTest, CopyBytesTo) +{ + constexpr uint8_t src[] = {1, 2, 3, 4, 5, 6, 7, 8}; + SpanId id(src); + uint8_t buf[8]; + id.CopyBytesTo(buf); + EXPECT_TRUE(memcmp(src, buf, 8) == 0); +} +} // namespace