diff options
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/sdk/src/common')
11 files changed, 436 insertions, 0 deletions
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/BUILD b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/BUILD new file mode 100644 index 000000000..b8369fc6f --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/BUILD @@ -0,0 +1,44 @@ +# 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. + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "random", + srcs = [ + "core.cc", + "random.cc", + ], + hdrs = [ + "fast_random_number_generator.h", + "random.h", + ], + include_prefix = "src/common", + deps = [ + "//api", + "//sdk:headers", + "//sdk/src/common/platform:fork", + ], +) + +cc_library( + name = "global_log_handler", + srcs = [ + "global_log_handler.cc", + ], + deps = [ + "//api", + "//sdk:headers", + ], +) diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/CMakeLists.txt b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/CMakeLists.txt new file mode 100644 index 000000000..d8674353b --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/CMakeLists.txt @@ -0,0 +1,21 @@ +set(COMMON_SRCS random.cc core.cc global_log_handler.cc) +if(WIN32) + list(APPEND COMMON_SRCS platform/fork_windows.cc) +else() + list(APPEND COMMON_SRCS platform/fork_unix.cc) +endif() + +add_library(opentelemetry_common ${COMMON_SRCS}) + +set_target_properties(opentelemetry_common PROPERTIES EXPORT_NAME common) + +target_link_libraries( + opentelemetry_common PUBLIC opentelemetry_api opentelemetry_sdk + Threads::Threads) + +install( + TARGETS opentelemetry_common + EXPORT "${PROJECT_NAME}-target" + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/core.cc b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/core.cc new file mode 100644 index 000000000..16012e765 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/core.cc @@ -0,0 +1,8 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// clang-format off +// version.h should be included before nostd/variant.h. +#include "opentelemetry/version.h" +#include "opentelemetry/nostd/variant.h" +// clang-format on diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/fast_random_number_generator.h b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/fast_random_number_generator.h new file mode 100644 index 000000000..9887f2f3b --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/fast_random_number_generator.h @@ -0,0 +1,82 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include <array> +#include <cstdint> +#include <limits> + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +/** + * Profiling shows that random number generation can be a significant cost of + * span generation. This provides a faster random number generator than + * std::mt19937_64; and since we don't care about the other beneficial random + * number properties that std:mt19937_64 provides for this application, it's a + * entirely appropriate replacement. + * + * Note for Windows users - please make sure that NOMINMAX is defined, e.g. + * + * ... + * #define NOMINMAX + * #include <Windows.h> + * ... + * + * See: + * https://stackoverflow.com/questions/13416418/define-nominmax-using-stdmin-max + * + */ +class FastRandomNumberGenerator +{ +public: + using result_type = uint64_t; + + FastRandomNumberGenerator() noexcept = default; + + template <class SeedSequence> + FastRandomNumberGenerator(SeedSequence &seed_sequence) noexcept + { + seed(seed_sequence); + } + + uint64_t operator()() noexcept + { + // Uses the xorshift128p random number generation algorithm described in + // https://en.wikipedia.org/wiki/Xorshift + auto &state_a = state_[0]; + auto &state_b = state_[1]; + auto t = state_a; + auto s = state_b; + state_a = s; + t ^= t << 23; // a + t ^= t >> 17; // b + t ^= s ^ (s >> 26); // c + state_b = t; + return t + s; + } + + // RandomNumberGenerator concept functions required from standard library. + // See http://www.cplusplus.com/reference/random/mt19937/ + template <class SeedSequence> + void seed(SeedSequence &seed_sequence) noexcept + { + seed_sequence.generate(reinterpret_cast<uint32_t *>(state_.data()), + reinterpret_cast<uint32_t *>(state_.data() + state_.size())); + } + + static constexpr uint64_t min() noexcept { return 0; } + + static constexpr uint64_t max() noexcept { return std::numeric_limits<uint64_t>::max(); } + +private: + std::array<uint64_t, 2> state_{}; +}; +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/global_log_handler.cc b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/global_log_handler.cc new file mode 100644 index 000000000..c86b652c7 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/global_log_handler.cc @@ -0,0 +1,57 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "opentelemetry/sdk/common/global_log_handler.h" + +#include <cstring> +#include <random> + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +namespace internal_log +{ + +LogHandler::~LogHandler() {} + +void DefaultLogHandler::Handle(LogLevel level, + const char *file, + int line, + const char *msg, + const sdk::common::AttributeMap &attributes) noexcept +{ + std::stringstream output_s; + output_s << "[" << LevelToString(level) << "] "; + if (file != nullptr) + { + output_s << "File: " << file << ":" << line; + } + if (msg != nullptr) + { + output_s << msg; + } + output_s << std::endl; + // TBD - print attributes + std::cout << output_s.str(); // thread safe. +} + +void NoopLogHandler::Handle(LogLevel, + const char *, + int, + const char *, + const sdk::common::AttributeMap &) noexcept +{} + +std::pair<nostd::shared_ptr<LogHandler>, LogLevel> &GlobalLogHandler::GetHandlerAndLevel() noexcept +{ + static std::pair<nostd::shared_ptr<LogHandler>, LogLevel> handler_and_level{ + nostd::shared_ptr<LogHandler>(new DefaultLogHandler), LogLevel::Warning}; + return handler_and_level; +} + +} // namespace internal_log +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/BUILD b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/BUILD new file mode 100644 index 000000000..c96a1417a --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/BUILD @@ -0,0 +1,34 @@ +# 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. + +package(default_visibility = ["//visibility:public"]) + +cc_library( + name = "fork", + srcs = select({ + "//bazel:windows": ["fork_windows.cc"], + "//conditions:default": ["fork_unix.cc"], + }), + hdrs = [ + "fork.h", + ], + include_prefix = "src/common/platform", + linkopts = select({ + "//bazel:windows": [], + "//conditions:default": ["-pthread"], + }), + deps = [ + "//api", + ], +) diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork.h b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork.h new file mode 100644 index 000000000..b1a0e9d77 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork.h @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +namespace platform +{ +/** + * Portable wrapper for pthread_atfork. + * See + * https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html + */ +int AtFork(void (*prepare)(), void (*parent)(), void (*child)()) noexcept; +} // namespace platform +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork_unix.cc b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork_unix.cc new file mode 100644 index 000000000..cfbd8ab77 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork_unix.cc @@ -0,0 +1,22 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "src/common/platform/fork.h" + +#include <pthread.h> + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +namespace platform +{ +int AtFork(void (*prepare)(), void (*parent)(), void (*child)()) noexcept +{ + return ::pthread_atfork(prepare, parent, child); +} +} // namespace platform +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork_windows.cc b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork_windows.cc new file mode 100644 index 000000000..9d9f2bf79 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/platform/fork_windows.cc @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "src/common/platform/fork.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +namespace platform +{ +int AtFork(void (*prepare)(), void (*parent)(), void (*child)()) noexcept +{ + (void)prepare; + (void)parent; + (void)child; + return 0; +} +} // namespace platform +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/random.cc b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/random.cc new file mode 100644 index 000000000..77b88cfa2 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/random.cc @@ -0,0 +1,80 @@ + +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "src/common/random.h" +#include "src/common/platform/fork.h" + +#include <cstring> +#include <random> + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +// Wraps a thread_local random number generator, but adds a fork handler so that +// the generator will be correctly seeded after forking. +// +// See https://stackoverflow.com/q/51882689/4447365 and +// https://github.com/opentracing-contrib/nginx-opentracing/issues/52 +namespace +{ +class TlsRandomNumberGenerator +{ +public: + TlsRandomNumberGenerator() noexcept + { + Seed(); + platform::AtFork(nullptr, nullptr, OnFork); + } + + static FastRandomNumberGenerator &engine() noexcept { return engine_; } + +private: + static thread_local FastRandomNumberGenerator engine_; + + static void OnFork() noexcept { Seed(); } + + static void Seed() noexcept + { + std::random_device random_device; + std::seed_seq seed_seq{random_device(), random_device(), random_device(), random_device()}; + engine_.seed(seed_seq); + } +}; + +thread_local FastRandomNumberGenerator TlsRandomNumberGenerator::engine_{}; +} // namespace + +FastRandomNumberGenerator &Random::GetRandomNumberGenerator() noexcept +{ + static thread_local TlsRandomNumberGenerator random_number_generator{}; + return TlsRandomNumberGenerator::engine(); +} + +uint64_t Random::GenerateRandom64() noexcept +{ + return GetRandomNumberGenerator()(); +} + +void Random::GenerateRandomBuffer(opentelemetry::nostd::span<uint8_t> buffer) noexcept +{ + auto buf_size = buffer.size(); + + for (size_t i = 0; i < buf_size; i += sizeof(uint64_t)) + { + uint64_t value = GenerateRandom64(); + if (i + sizeof(uint64_t) <= buf_size) + { + memcpy(&buffer[i], &value, sizeof(uint64_t)); + } + else + { + memcpy(&buffer[i], &value, buf_size - i); + } + } +} +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/src/common/random.h b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/random.h new file mode 100644 index 000000000..ecd6dabc1 --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/src/common/random.h @@ -0,0 +1,41 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/nostd/span.h" +#include "opentelemetry/version.h" +#include "src/common/fast_random_number_generator.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +/** + * Utility methods for creating random data, based on a seeded thread-local + * number generator. + */ +class Random +{ +public: + /** + * @return an unsigned 64 bit random number + */ + static uint64_t GenerateRandom64() noexcept; + /** + * Fill the passed span with random bytes. + * + * @param buffer A span of bytes. + */ + static void GenerateRandomBuffer(opentelemetry::nostd::span<uint8_t> buffer) noexcept; + +private: + /** + * @return a seeded thread-local random number generator. + */ + static FastRandomNumberGenerator &GetRandomNumberGenerator() noexcept; +}; +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE |