From 36bdeaec8c0dde02027a09978cfd0432a7e45d95 Mon Sep 17 00:00:00 2001 From: John Elliott Date: Wed, 28 Feb 2024 14:45:08 -0800 Subject: [PATCH] Move DynamicEvent from eden to edencommon Summary: To support better telemetry and logging in watchman we want to use Eden's components. Lets migrate and detangle the needed pieces. This change move DynamicEvent from eden to edencommon. Reviewed By: kmancini Differential Revision: D54046154 fbshipit-source-id: de9466c73c0b2a2a16302cc0114e4c2a12426b30 --- CMakeLists.txt | 1 + eden/common/telemetry/CMakeLists.txt | 39 +++++++++++++++++ eden/common/telemetry/DynamicEvent.cpp | 55 ++++++++++++++++++++++++ eden/common/telemetry/DynamicEvent.h | 59 ++++++++++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 eden/common/telemetry/CMakeLists.txt create mode 100644 eden/common/telemetry/DynamicEvent.cpp create mode 100644 eden/common/telemetry/DynamicEvent.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 62cffe24..b998c567 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ include(GoogleTest) enable_testing() add_subdirectory(eden/common/os) +add_subdirectory(eden/common/telemetry) add_subdirectory(eden/common/utils) # Install our own CMake package files for dependent projects. diff --git a/eden/common/telemetry/CMakeLists.txt b/eden/common/telemetry/CMakeLists.txt new file mode 100644 index 00000000..f60d1b96 --- /dev/null +++ b/eden/common/telemetry/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +file(GLOB telemetry_headers CONFIGURE_DEPENDS *.h) +file(GLOB telemetry_sources CONFIGURE_DEPENDS *.cpp) + +add_library( + edencommon_telemetry + ${telemetry_headers} + ${telemetry_sources}) + +target_link_libraries( + edencommon_telemetry + PUBLIC + edencommon_utils + Folly::folly +) + + +target_include_directories( + edencommon_telemetry + PUBLIC + $ + $ +) + +install( + TARGETS edencommon_telemetry + EXPORT edencommon-exports + LIBRARY DESTINATION "${LIB_INSTALL_DIR}" + ARCHIVE DESTINATION "${LIB_INSTALL_DIR}" +) + +install( + FILES ${telemetry_headers} + DESTINATION ${INCLUDE_INSTALL_DIR}/eden/common/telemetry +) diff --git a/eden/common/telemetry/DynamicEvent.cpp b/eden/common/telemetry/DynamicEvent.cpp new file mode 100644 index 00000000..28bb0f5c --- /dev/null +++ b/eden/common/telemetry/DynamicEvent.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "eden/common/telemetry/DynamicEvent.h" + +#include +#include +#include +#include "eden/common/utils/Throw.h" + +namespace { +void validateUtf8(folly::StringPiece sp) { + auto* p = reinterpret_cast(sp.begin()); + auto* const end = reinterpret_cast(sp.end()); + while (p < end) { + (void)folly::utf8ToCodePoint(p, end, false); + } +} +} // namespace + +namespace facebook::eden { + +void DynamicEvent::addInt(std::string name, int64_t value) { + auto [iter, inserted] = ints_.emplace(std::move(name), value); + if (!inserted) { + throw_( + "Attempted to insert duplicate int: ", iter->first); + } +} + +void DynamicEvent::addString(std::string name, std::string value) { + validateUtf8(value); + auto [iter, inserted] = strings_.emplace(std::move(name), std::move(value)); + if (!inserted) { + throw_( + "Attempted to insert duplicate string: ", iter->first); + } +} + +void DynamicEvent::addDouble(std::string name, double value) { + XCHECK(std::isfinite(value)) + << "Attempted to insert double-precision value that cannot be represented in JSON: " + << name; + auto [iter, inserted] = doubles_.emplace(std::move(name), value); + if (!inserted) { + throw_( + "Attempted to insert duplicate double: ", iter->first); + } +} + +} // namespace facebook::eden diff --git a/eden/common/telemetry/DynamicEvent.h b/eden/common/telemetry/DynamicEvent.h new file mode 100644 index 00000000..e0475456 --- /dev/null +++ b/eden/common/telemetry/DynamicEvent.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +namespace facebook::eden { + +class DynamicEvent { + public: + using IntMap = std::unordered_map; + using StringMap = std::unordered_map; + using DoubleMap = std::unordered_map; + + DynamicEvent() = default; + DynamicEvent(const DynamicEvent&) = default; + DynamicEvent(DynamicEvent&&) = default; + DynamicEvent& operator=(const DynamicEvent&) = default; + DynamicEvent& operator=(DynamicEvent&&) = default; + + void addInt(std::string name, int64_t value); + void addString(std::string name, std::string value); + void addDouble(std::string name, double value); + + /** + * Convenience function that adds boolean values as integer 0 or 1. + */ + void addBool(std::string name, bool value) { + addInt(std::move(name), value); + } + + const IntMap& getIntMap() const { + return ints_; + } + const StringMap& getStringMap() const { + return strings_; + } + const DoubleMap& getDoubleMap() const { + return doubles_; + } + + private: + // Due to limitations in the underlying log database, limit the field types to + // int64_t, double, string, and vector + // TODO: add vector support if needed. + IntMap ints_; + StringMap strings_; + DoubleMap doubles_; +}; + +} // namespace facebook::eden