diff --git a/api/include/opentelemetry/trace/trace_flags.h b/api/include/opentelemetry/trace/trace_flags.h new file mode 100644 index 00000000000..05724a50616 --- /dev/null +++ b/api/include/opentelemetry/trace/trace_flags.h @@ -0,0 +1,63 @@ +// Copyright 2020, 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 +{ + +// TraceFlags represents options for a Trace. These options are propagated to all child Spans +// and determine features such as whether a Span should be traced. TraceFlags +// are implemented as a bitmask. +class TraceFlags final +{ +public: + static constexpr uint8_t kIsSampled = 1; + + TraceFlags() noexcept : rep_{0} {} + + explicit TraceFlags(uint8_t flags) noexcept : rep_(flags) {} + + bool IsSampled() const noexcept { return rep_ & kIsSampled; } + + // Populates the buffer with the lowercase base16 representation of the flags. + void ToLowerBase16(nostd::span buffer) const noexcept + { + constexpr char kHex[] = "0123456789ABCDEF"; + buffer[0] = kHex[(rep_ >> 4) & 0xF]; + buffer[1] = kHex[(rep_ >> 0) & 0xF]; + } + + uint8_t flags() const noexcept { return rep_; } + + bool operator==(const TraceFlags &that) const noexcept { return rep_ == that.rep_; } + + bool operator!=(const TraceFlags &that) const noexcept { return !(*this == that); } + + // Copies the TraceFlags to dest. + void CopyBytesTo(nostd::span dest) const noexcept { dest[0] = rep_; } + +private: + uint8_t rep_; +}; + +} // namespace trace +} // namespace opentelemetry diff --git a/api/test/trace/BUILD b/api/test/trace/BUILD index 9098162e593..a8e8507e4eb 100644 --- a/api/test/trace/BUILD +++ b/api/test/trace/BUILD @@ -28,6 +28,17 @@ cc_test( ], ) +cc_test( + name = "trace_flags_test", + srcs = [ + "trace_flags_test.cc", + ], + deps = [ + "//api", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "trace_id_test", srcs = [ diff --git a/api/test/trace/CMakeLists.txt b/api/test/trace/CMakeLists.txt index 1f83795886c..a74adb39fee 100644 --- a/api/test/trace/CMakeLists.txt +++ b/api/test/trace/CMakeLists.txt @@ -16,3 +16,9 @@ add_executable(trace_id_test trace_id_test.cc) target_link_libraries(trace_id_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) gtest_add_tests(TARGET trace_id_test TEST_PREFIX trace. TEST_LIST trace_id_test) + +add_executable(trace_flags_test trace_flags_test.cc) +target_link_libraries(trace_flags_test ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) +gtest_add_tests(TARGET trace_flags_test TEST_PREFIX trace. TEST_LIST + trace_flags_test) diff --git a/api/test/trace/trace_flags_test.cc b/api/test/trace/trace_flags_test.cc new file mode 100644 index 00000000000..21e737eabc6 --- /dev/null +++ b/api/test/trace/trace_flags_test.cc @@ -0,0 +1,40 @@ +#include "opentelemetry/trace/trace_flags.h" + +#include +#include + +#include + +namespace +{ + +using opentelemetry::trace::TraceFlags; + +std::string Hex(const TraceFlags &flags) +{ + char buf[2]; + flags.ToLowerBase16(buf); + return std::string(buf, sizeof(buf)); +} + +TEST(TraceFlagsTest, DefaultConstruction) +{ + TraceFlags flags; + EXPECT_FALSE(flags.IsSampled()); + EXPECT_EQ(0, flags.flags()); + EXPECT_EQ("00", Hex(flags)); +} + +TEST(TraceFlagsTest, Sampled) +{ + TraceFlags flags{TraceFlags::kIsSampled}; + EXPECT_TRUE(flags.IsSampled()); + EXPECT_EQ(1, flags.flags()); + EXPECT_EQ("01", Hex(flags)); + + uint8_t buf[1]; + flags.CopyBytesTo(buf); + EXPECT_EQ(1, buf[0]); +} + +} // namespace