diff --git a/src/bk_download.cpp b/src/bk_download.cpp index c8a06b86..b2e5f7a5 100644 --- a/src/bk_download.cpp +++ b/src/bk_download.cpp @@ -276,11 +276,11 @@ bool BkDownload::download_blob() { return true; } -void bk_download_proc(std::list &dl_list, uint64_t delay_sec, int &running) { +void bk_download_proc(std::list &dl_list, uint64_t delay_sec, int &running, opentelemetry::trace::SpanContext linkContext) { auto tracer = overlaybd_otel::GetTracer(); auto span = tracer->StartSpan("background_download_process"); + span->AddLink(linkContext, {}); auto scope = tracer->WithActiveSpan(span); - span->SetAttribute("delay_seconds", delay_sec); span->SetAttribute("initial_queue_size", dl_list.size()); diff --git a/src/bk_download.h b/src/bk_download.h index d5962725..313bb490 100644 --- a/src/bk_download.h +++ b/src/bk_download.h @@ -67,6 +67,6 @@ class BkDownload { bool force_download = false; }; -void bk_download_proc(std::list &, uint64_t, int &); +void bk_download_proc(std::list &, uint64_t, int &, opentelemetry::trace::SpanContext); } // namespace BKDL \ No newline at end of file diff --git a/src/config.h b/src/config.h index 8df7f62e..caa19e04 100644 --- a/src/config.h +++ b/src/config.h @@ -65,6 +65,7 @@ struct ImageConfig : public ConfigUtils::Config { APPCFG_PARA(download, DownloadConfig); APPCFG_PARA(accelerationLayer, bool, false); APPCFG_PARA(recordTracePath, std::string, ""); + APPCFG_PARA(traceContext, ConfigUtils::Document); }; struct P2PConfig : public ConfigUtils::Config { diff --git a/src/image_file.cpp b/src/image_file.cpp index df3169b9..04b71f19 100644 --- a/src/image_file.cpp +++ b/src/image_file.cpp @@ -35,6 +35,7 @@ #include "switch_file.h" #include "overlaybd/gzip/gz.h" #include "overlaybd/gzindex/gzfile.h" +#include "overlaybd/otel/tracer_common.h" #include "overlaybd/tar/tar_file.h" #define PARALLEL_LOAD_INDEX 32 @@ -217,8 +218,10 @@ void ImageFile::start_bk_dl_thread() { uint64_t delay_sec = (rand() % extra_range) + conf.download().delay(); LOG_INFO("background download is enabled, delay `, maxMBps `, tryCnt `, blockSize `", delay_sec, conf.download().maxMBps(), conf.download().tryCnt(), conf.download().blockSize()); + opentelemetry::trace::SpanContext linkContext = overlaybd_otel::GetTracer()->GetCurrentSpan()->GetContext(); dl_thread_jh = photon::thread_enable_join( - photon::thread_create11(&BKDL::bk_download_proc, dl_list, delay_sec, m_status)); + photon::thread_create11( + BKDL::bk_download_proc, dl_list, delay_sec, m_status, std::move(linkContext))); } struct ParallelOpenTask { @@ -437,6 +440,15 @@ LSMT::IFileRW *ImageFile::open_upper(ImageConfigNS::UpperConfig &upper) { } int ImageFile::init_image_file() { + // Extracts the trace context from the image config as a parent context. + // This allows us to link activity associated with overlaybd-snapshotter. + auto parent_context = overlaybd_otel::ExtractTraceContext(conf.traceContext()); + auto tracer = overlaybd_otel::GetTracer(); + opentelemetry::trace::StartSpanOptions opts; + opts.parent = parent_context; + auto span = tracer->StartSpan("ImageFile::init_image_file", opts); + auto scope = tracer->WithActiveSpan(span); + LSMT::IFileRO *lower_file = nullptr; LSMT::IFileRW *upper_file = nullptr; LSMT::IFileRW *stack_ret = nullptr; diff --git a/src/overlaybd/otel/CMakeLists.txt b/src/overlaybd/otel/CMakeLists.txt index f4021b7f..ab983c27 100644 --- a/src/overlaybd/otel/CMakeLists.txt +++ b/src/overlaybd/otel/CMakeLists.txt @@ -26,6 +26,7 @@ set_target_properties(otel_lib PROPERTIES LINKER_LANGUAGE CXX) target_include_directories(otel_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${PHOTON_INCLUDE_DIR} + ${rapidjson_SOURCE_DIR}/include ${opentelemetry-cpp_SOURCE_DIR}/api/include ${opentelemetry-cpp_SOURCE_DIR}/sdk/include ${opentelemetry-cpp_SOURCE_DIR}/exporters/otlp/include diff --git a/src/overlaybd/otel/tracer_common.cpp b/src/overlaybd/otel/tracer_common.cpp index dab69679..96c1cd3c 100644 --- a/src/overlaybd/otel/tracer_common.cpp +++ b/src/overlaybd/otel/tracer_common.cpp @@ -1,13 +1,19 @@ -#include "opentelemetry/context/runtime_context.h" #include "tracer_common.h" + #include "context_storage.h" +#include "opentelemetry/context/runtime_context.h" + +using opentelemetry::nostd::unique_ptr; +using opentelemetry::nostd::shared_ptr; +using opentelemetry::nostd::string_view; +using opentelemetry::nostd::function_ref; namespace overlaybd_otel { void InitTracer() { // Install a libphoton coroutine-aware context storage implementation, which uses libphoton's thread-local implementation. opentelemetry::context::RuntimeContext::SetRuntimeContextStorage( - opentelemetry::nostd::unique_ptr( + unique_ptr( new LibPhotonContextStorage())); // Create OTLP/HTTP exporter using the factory @@ -26,12 +32,44 @@ void InitTracer() { } void CleanupTracer() { - std::shared_ptr none; - opentelemetry::sdk::trace::Provider::SetTracerProvider(none); + opentelemetry::sdk::trace::Provider::SetTracerProvider({}); } opentelemetry::nostd::shared_ptr GetTracer(opentelemetry::nostd::string_view tracer_name) { return opentelemetry::trace::Provider::GetTracerProvider()->GetTracer(tracer_name); } +class JsonTextMapCarrier : public opentelemetry::context::propagation::TextMapCarrier { +public: + JsonTextMapCarrier(const rapidjson::Document& traceContext): m_traceContext(traceContext) {} + + string_view Get(string_view key) const noexcept override { + for (auto iter = m_traceContext.MemberBegin(); iter != m_traceContext.MemberEnd(); ++iter) { + if (key == iter->name.GetString() && iter->value.IsString()) { + return iter->value.GetString(); + } + } + return {}; + } + + void Set(string_view key, string_view value) noexcept override { + // not implemented + } + +private: + const rapidjson::Document& m_traceContext; +}; + +opentelemetry::context::Context ExtractTraceContext(const rapidjson::Document& document) { + if (!document.IsObject()) { + return {}; + } + + // Extract the traceContext if it exists. + opentelemetry::context::Context context; + auto carrier = JsonTextMapCarrier(document); + auto propagator = opentelemetry::trace::propagation::HttpTraceContext(); + return propagator.Extract(carrier, context); +} + } // namespace overlaybd_otel diff --git a/src/overlaybd/otel/tracer_common.h b/src/overlaybd/otel/tracer_common.h index 2613056e..615fc268 100644 --- a/src/overlaybd/otel/tracer_common.h +++ b/src/overlaybd/otel/tracer_common.h @@ -1,7 +1,7 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - #pragma once + +#define OPENTELEMETRY_ABI_VERSION_NO 2 + #include "opentelemetry/exporters/otlp/otlp_http_exporter_factory.h" #include "opentelemetry/exporters/otlp/otlp_http_exporter_options.h" #include "opentelemetry/nostd/shared_ptr.h" @@ -20,11 +20,16 @@ #include #include -namespace overlaybd_otel { +#include +namespace overlaybd_otel { void InitTracer(); + void CleanupTracer(); + opentelemetry::nostd::shared_ptr GetTracer(opentelemetry::nostd::string_view tracer_name = "overlaybd"); +opentelemetry::context::Context ExtractTraceContext(const rapidjson::Document& config); + } // namespace overlaybd_otel \ No newline at end of file