From 2e0dd19bac02a5bc3d8f59b900b9ea014554bb34 Mon Sep 17 00:00:00 2001 From: antonio2368 Date: Mon, 8 Mar 2021 15:15:58 +0100 Subject: [PATCH] Add machine-id to telemetry if not docker (#103) * Add machine-id to telemetry if not docker * Improve telemetry integration test --- CMakeLists.txt | 3 +++ src/telemetry/CMakeLists.txt | 3 +++ src/telemetry/telemetry.cpp | 28 +++++++++++++++++++++++---- src/telemetry/telemetry.hpp | 6 +++--- tests/integration/telemetry/server.py | 13 +++++++++---- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ca9ac487..0b54ae29c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,9 @@ else() message(FATAL_ERROR "Couldn't find clang and/or clang++!") endif() +option(BUILD_FOR_DOCKER "Build Memgraph binary for docker." OFF) +message(STATUS "BUILD_FOR_DOCKER: ${BUILD_FOR_DOCKER}") + # ----------------------------------------------------------------------------- project(memgraph) diff --git a/src/telemetry/CMakeLists.txt b/src/telemetry/CMakeLists.txt index ba0a53f8f..1f5484588 100644 --- a/src/telemetry/CMakeLists.txt +++ b/src/telemetry/CMakeLists.txt @@ -5,3 +5,6 @@ set(telemetry_src_files add_library(telemetry_lib STATIC ${telemetry_src_files}) target_link_libraries(telemetry_lib mg-requests mg-kvstore mg-utils) +if (BUILD_FOR_DOCKER) + target_compile_definitions(telemetry_lib PRIVATE DOCKER_BUILD) +endif() diff --git a/src/telemetry/telemetry.cpp b/src/telemetry/telemetry.cpp index dadba6843..77207353b 100644 --- a/src/telemetry/telemetry.cpp +++ b/src/telemetry/telemetry.cpp @@ -7,17 +7,36 @@ #include "requests/requests.hpp" #include "telemetry/collectors.hpp" #include "telemetry/system_info.hpp" +#include "utils/file.hpp" #include "utils/logging.hpp" #include "utils/timestamp.hpp" #include "utils/uuid.hpp" namespace telemetry { +namespace { +std::string GetMachineId() { +#ifdef DOCKER_BUILD + return "DOCKER"; +#else + // We assume we're on linux and we need to read the machine id from /etc/machine-id + const auto machine_id_lines = utils::ReadLines("/etc/machine-id"); + if (machine_id_lines.size() != 1) { + return "UNKNOWN"; + } + return machine_id_lines[0]; +#endif +} +} // namespace const int kMaxBatchSize = 100; -Telemetry::Telemetry(const std::string &url, const std::filesystem::path &storage_directory, - std::chrono::duration refresh_interval, const uint64_t send_every_n) - : url_(url), uuid_(utils::GenerateUUID()), send_every_n_(send_every_n), storage_(storage_directory) { +Telemetry::Telemetry(std::string url, std::filesystem::path storage_directory, + std::chrono::duration refresh_interval, const uint64_t send_every_n) + : url_(std::move(url)), + uuid_(utils::GenerateUUID()), + machine_id_(GetMachineId()), + send_every_n_(send_every_n), + storage_(std::move(storage_directory)) { StoreData("startup", GetSystemInfo()); AddCollector("resources", GetResourceUsage); AddCollector("uptime", [&]() -> nlohmann::json { return GetUptime(); }); @@ -35,7 +54,8 @@ Telemetry::~Telemetry() { } void Telemetry::StoreData(const nlohmann::json &event, const nlohmann::json &data) { - nlohmann::json payload = {{"id", uuid_}, + nlohmann::json payload = {{"run_id", uuid_}, + {"machine_id", machine_id_}, {"event", event}, {"data", data}, {"timestamp", utils::Timestamp::Now().SecWithNsecSinceTheEpoch()}}; diff --git a/src/telemetry/telemetry.hpp b/src/telemetry/telemetry.hpp index e9320e515..7006b5fb9 100644 --- a/src/telemetry/telemetry.hpp +++ b/src/telemetry/telemetry.hpp @@ -23,9 +23,8 @@ namespace telemetry { */ class Telemetry final { public: - Telemetry(const std::string &url, const std::filesystem::path &storage_directory, - std::chrono::duration refresh_interval = std::chrono::minutes(10), - const uint64_t send_every_n = 10); + Telemetry(std::string url, std::filesystem::path storage_directory, + std::chrono::duration refresh_interval = std::chrono::minutes(10), uint64_t send_every_n = 10); void AddCollector(const std::string &name, const std::function &func); @@ -45,6 +44,7 @@ class Telemetry final { const std::string url_; const std::string uuid_; + const std::string machine_id_; uint64_t num_{0}; utils::Scheduler scheduler_; utils::Timer timer_; diff --git a/tests/integration/telemetry/server.py b/tests/integration/telemetry/server.py index 94026d686..a4ebf9cae 100755 --- a/tests/integration/telemetry/server.py +++ b/tests/integration/telemetry/server.py @@ -5,6 +5,7 @@ import os import signal import sys import time +import itertools from http.server import BaseHTTPRequestHandler, HTTPServer @@ -56,7 +57,8 @@ def build_handler(storage, args): for item in data: assert type(item) == dict assert "event" in item - assert "id" in item + assert "run_id" in item + assert "machine_id" in item assert "data" in item assert "timestamp" in item storage.append(item) @@ -94,10 +96,10 @@ def item_sort_key(obj): def verify_storage(storage, args): - rid = storage[0]["id"] + rid = storage[0]["run_id"] timestamp = 0 for i, item in enumerate(storage): - assert item["id"] == rid + assert item["run_id"] == rid assert item["timestamp"] >= timestamp timestamp = item["timestamp"] @@ -169,7 +171,7 @@ if __name__ == "__main__": # Split the data into individual startups. startups = [[storage[0]]] for item in storage[1:]: - if item["id"] != startups[-1][-1]["id"]: + if item["run_id"] != startups[-1][-1]["run_id"]: startups.append([]) startups[-1].append(item) @@ -179,3 +181,6 @@ if __name__ == "__main__": # Verify each startup. for startup in startups: verify_storage(startup, args) + + # machine id has to be same for every run on the same machine + assert len(set(map(lambda x: x['machine_id'], itertools.chain(*startups)))) == 1