diff --git a/recipes-support/opentelemetry/opentelemetry-cpp_1.20.0.bb b/recipes-support/opentelemetry/opentelemetry-cpp_1.20.0.bb new file mode 100644 index 00000000..bd3f94da --- /dev/null +++ b/recipes-support/opentelemetry/opentelemetry-cpp_1.20.0.bb @@ -0,0 +1,81 @@ + +SUMMARY = "OpenTelemetry C++ SDK and API" +DESCRIPTION = "C++ implementation of OpenTelemetry for traces, metrics, and logs." +HOMEPAGE = "https://github.com/open-telemetry/opentelemetry-cpp" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +PV = "1.20.0" +SRC_URI = "gitsm://github.com/open-telemetry/opentelemetry-cpp.git;branch=main" +SRCREV = "6175aa0b213eea053247e43b4f35b8d201fa356e" + +PACKAGE_ARCH = "${MIDDLEWARE_ARCH}" + +FILESEXTRAPATHS:prepend := "${THISDIR}/opentelemetry:" +# Bring in patch that links absl::strings from Abseil +SRC_URI += "file://0001-link-absl-strings-into-common.patch" + +S = "${WORKDIR}/git" + +inherit cmake pkgconfig + +DEPENDS = "\ + grpc \ + protobuf \ + abseil-cpp \ + nlohmann-json \ + curl \ + re2 \ + c-ares \ + openssl \ +" + +DEPENDS += "protobuf-native grpc-native" + +PACKAGECONFIG ??= "otlp_grpc" +PACKAGECONFIG[otlp_grpc] = "-DWITH_OTLP_GRPC=ON,-DWITH_OTLP_GRPC=OFF,grpc protobuf" +PACKAGECONFIG[otlp_http] = "-DWITH_OTLP_HTTP=ON,-DWITH_OTLP_HTTP=OFF,curl nlohmann-json" +PACKAGECONFIG[otlp_prometheus]= "-DWITH_PROMETHEUS=ON,-DWITH_PROMETHEUS=OFF,prometheus-cpp" +PACKAGECONFIG[benchmark] = "-DWITH_BENCHMARK=ON,-DWITH_BENCHMARK=OFF,benchmark" +PACKAGECONFIG[testing] = "-DWITH_TESTING=ON,-DWITH_TESTING=OFF,gtest" + +EXTRA_OECMAKE += "\ + -DBUILD_SHARED_LIBS=ON \ + -DWITH_ABSEIL=OFF \ + -DWITH_STL=CXX17 \ + -Dabsl_DIR=${RECIPE_SYSROOT}/usr/lib/cmake/absl \ +" + +# Point CMake at native protoc + grpc_cpp_plugin +EXTRA_OECMAKE += "\ + -DProtobuf_PROTOC_EXECUTABLE=${STAGING_BINDIR_NATIVE}/protoc \ + -DgRPC_CPP_PLUGIN=${STAGING_BINDIR_NATIVE}/grpc_cpp_plugin \ +" + +EXTRA_OECMAKE += "-DCMAKE_CXX_FLAGS_append=' -D_GLIBCXX_USE_CXX11_ABI=1'" +TARGET_LDFLAGS:append = " -Wl,--no-as-needed" + + + +EXTRA_OECMAKE += "\ + -DBUILD_SHARED_LIBS=ON \ + -DWITH_ABI_VERSION_1=ON \ + -DWITH_ABI_VERSION_2=OFF \ + -DWITH_STL=OFF \ + -DCMAKE_CXX_STANDARD=17 \ +" + +# Treat unversioned .so as runtime libs +SOLIBS = ".so" +FILES:${PN} += "${libdir}/*.so" + +# Prevent Yocto from classifying them as -dev +SOLIBSDEV = "" +INSANE_SKIP:${PN} += "dev-so" + +# Explicitly define -dev content so it does NOT include ${libdir}/*.so +FILES:${PN}-dev = "\ + ${includedir} \ + ${libdir}/pkgconfig \ + ${libdir}/cmake \ +" diff --git a/recipes-support/opentelemetry/opentelemetry-examples/CMakeLists.txt b/recipes-support/opentelemetry/opentelemetry-examples/CMakeLists.txt new file mode 100644 index 00000000..3d2834a5 --- /dev/null +++ b/recipes-support/opentelemetry/opentelemetry-examples/CMakeLists.txt @@ -0,0 +1,51 @@ + +cmake_minimum_required(VERSION 3.10) +project(otlp_grpc_logging_example) + +set(CMAKE_CXX_STANDARD 14) + +find_package(opentelemetry-cpp CONFIG REQUIRED) + +add_executable(otlp_grpc_logging otlp_grpc_logging.cpp) + +target_link_libraries(otlp_grpc_logging + opentelemetry_logs + opentelemetry_exporter_otlp_grpc_log +) + + +set(LIB_VERSION "1.0.0") +set(LIB_SOVERSION "1") + +add_library(otlp_logger SHARED otlp_logger.cpp) + +set_target_properties(otlp_logger PROPERTIES + VERSION ${LIB_VERSION} + SOVERSION ${LIB_SOVERSION} +) + +target_include_directories(otlp_logger PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(otlp_logger PUBLIC + opentelemetry_common + opentelemetry_logs + opentelemetry_exporter_otlp_grpc_log + opentelemetry_exporter_ostream_logs +) + +# Install the library +install(TARGETS otlp_logger + DESTINATION ${CMAKE_INSTALL_LIBDIR}) + +# Install the header +install(FILES otlp_logger.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +add_executable(otlp-logger-example test_main.cpp) +target_link_libraries(otlp-logger-example PRIVATE otlp_logger) + +# Install the example executable +install(TARGETS otlp-logger-example + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + + + diff --git a/recipes-support/opentelemetry/opentelemetry-examples/otlp_grpc_logging.cpp b/recipes-support/opentelemetry/opentelemetry-examples/otlp_grpc_logging.cpp new file mode 100644 index 00000000..73f5597b --- /dev/null +++ b/recipes-support/opentelemetry/opentelemetry-examples/otlp_grpc_logging.cpp @@ -0,0 +1,32 @@ + +#include +#include +#include +#include +#include +#include + +using namespace opentelemetry::logs; +using namespace opentelemetry::sdk::logs; +using namespace opentelemetry::exporter::otlp; + +int main() +{ + auto exporter = std::unique_ptr(new OtlpGrpcLogRecordExporter()); + auto processor = std::unique_ptr(new SimpleLogRecordProcessor(std::move(exporter))); + + // Factory returns std::unique_ptr + auto provider_unique = LoggerProviderFactory::Create(std::move(processor)); + + // Disambiguate conversion to nostd::shared_ptr + opentelemetry::nostd::shared_ptr provider{ + provider_unique.release() // release raw pointer from unique_ptr + }; + + Provider::SetLoggerProvider(provider); + + auto logger = Provider::GetLoggerProvider()->GetLogger("example_logger"); + logger->EmitLogRecord("Hello from OTLP gRPC Logging Client!", Severity::kInfo); + + return 0; +} diff --git a/recipes-support/opentelemetry/opentelemetry-examples/otlp_logger.cpp b/recipes-support/opentelemetry/opentelemetry-examples/otlp_logger.cpp new file mode 100644 index 00000000..fc6bae5c --- /dev/null +++ b/recipes-support/opentelemetry/opentelemetry-examples/otlp_logger.cpp @@ -0,0 +1,130 @@ +#include "otlp_logger.h" +#include +#include +#include "opentelemetry/logs/logger_provider.h" +#include +#include "opentelemetry/sdk/logs/provider.h" +#include "opentelemetry/sdk/logs/logger_provider.h" +#include +#include +#include +#include +#include "opentelemetry/exporters/ostream/log_record_exporter.h" + +#include "opentelemetry/logs/logger_provider.h" +#include "opentelemetry/logs/provider.h" + +#include + +namespace logs_api = opentelemetry::logs; +namespace logs_sdk = opentelemetry::sdk::logs; +namespace logs_exporter = opentelemetry::exporter::otlp; +// namespace logs_exporter = opentelemetry::exporter::logs; + +namespace otlp_logger +{ + static std::once_flag init_flag; + static opentelemetry::nostd::shared_ptr logger; + + static void InitLogger() + { + // using namespace opentelemetry::sdk::logs; + // using namespace opentelemetry::exporter::otlp; + + auto exporter = std::unique_ptr(new logs_exporter::OtlpGrpcLogRecordExporter()); + + auto processor = logs_sdk::SimpleLogRecordProcessorFactory::Create(std::move(exporter)); + + std::shared_ptr sdk_provider( + opentelemetry::sdk::logs::LoggerProviderFactory::Create(std::move(processor))); + + const std::shared_ptr &api_provider = sdk_provider; + + // opentelemetry::logs::Provider::SetLoggerProvider(api_provider); + logs_sdk::Provider::SetLoggerProvider(api_provider); + + // GetLogger returns nostd::shared_ptr + auto provider = opentelemetry::logs::Provider::GetLoggerProvider(); + std::cout << "RSABAPATHI -- provider got successfully\n"; + + logger = provider->GetLogger("example_logger", "example"); + std::cout << "RSABAPATHI -- example_logger got\n"; + // logger = opentelemetry::logs::Provider::GetLoggerProvider()->GetLogger("example_logger"); + } + + void log_msg(opentelemetry::logs::Severity level, const std::string &msg) + { + // std::call_once(init_flag, init); + std::call_once(init_flag, InitLogger); + if (logger) + { + logger->EmitLogRecord(msg, level); + } + } + + // ---- helper: robust vsnprintf -> std::string ---- + + static std::string vformat_printf(const char *fmt, va_list args) + { + // First pass: compute required size (number of chars excluding '\0') + va_list args1; + va_copy(args1, args); + int needed = std::vsnprintf(nullptr, 0, fmt, args1); + va_end(args1); + + if (needed >= 0) + { + // Resize to exact number of chars; we’ll write with a trailing '\0' + std::string out; + out.resize(static_cast(needed)); + + va_list args2; + va_copy(args2, args); + // Write into string storage via non-const pointer in C++14 + std::vsnprintf(&out[0], static_cast(needed) + 1, fmt, args2); + va_end(args2); + + return out; // excludes the final '\0' + } + + // Fallback: grow a buffer until it fits (handles libcs that return -1) + std::vector buf(1024); + while (true) + { + va_list args3; + va_copy(args3, args); + int n = std::vsnprintf(buf.data(), buf.size(), fmt, args3); + va_end(args3); + + if (n >= 0 && static_cast(n) < buf.size()) + { + return std::string(buf.data(), static_cast(n)); + } + std::size_t new_size = (n >= 0) ? static_cast(n + 1) : buf.size() * 2; + buf.resize(new_size); + } + } + + // ---- new printf-style API ---- + void log_msgf(opentelemetry::logs::Severity level, const char *fmt, ...) + { + std::call_once(init_flag, InitLogger); + std::cout << "RSABAPATHI -- checking logger\n"; + if (!logger) + return; + + std::cout << "RSABAPATHI -- logger avaialble\n"; + + va_list args; + va_start(args, fmt); + std::string msg = vformat_printf(fmt, args); + va_end(args); + + // Use the same EmitLogRecord signature ordering as your existing code + std::cout << "RSABAPATHI -- Emitting Log Record\n"; + logger->EmitLogRecord(msg, level); + // If your SDK expects (Severity, Body), use: + // logger->EmitLogRecord(level, msg); + } + +} diff --git a/recipes-support/opentelemetry/opentelemetry-examples/otlp_logger.h b/recipes-support/opentelemetry/opentelemetry-examples/otlp_logger.h new file mode 100644 index 00000000..8841e98c --- /dev/null +++ b/recipes-support/opentelemetry/opentelemetry-examples/otlp_logger.h @@ -0,0 +1,15 @@ + +#ifndef OTLP_LOGGER_H +#define OTLP_LOGGER_H + +#include +#include + +namespace otlp_logger +{ + // Only expose log_msg to outside + void log_msg(opentelemetry::logs::Severity level, const std::string &msg); + void log_msgf(opentelemetry::logs::Severity level, const char *fmt, ...); +} + +#endif // OTLP_LOGGER_H diff --git a/recipes-support/opentelemetry/opentelemetry-examples/test_main.cpp b/recipes-support/opentelemetry/opentelemetry-examples/test_main.cpp new file mode 100644 index 00000000..db451f30 --- /dev/null +++ b/recipes-support/opentelemetry/opentelemetry-examples/test_main.cpp @@ -0,0 +1,14 @@ + +#include "otlp_logger.h" +#include + +#include + +int main() +{ + std::cout << "RSABAPATHI -- Logs to be sent now\n"; + otlp_logger::log_msgf(opentelemetry::logs::Severity::kInfo, "First log message triggers init(): %d\n", __LINE__); + otlp_logger::log_msgf(opentelemetry::logs::Severity::kError, "Second log message after init: %d", __LINE__); + std::cout << "RSABAPATHI -- Logs are sent\n"; + return 0; +} diff --git a/recipes-support/opentelemetry/opentelemetry-examples_1.0.bb b/recipes-support/opentelemetry/opentelemetry-examples_1.0.bb new file mode 100644 index 00000000..acabcf6b --- /dev/null +++ b/recipes-support/opentelemetry/opentelemetry-examples_1.0.bb @@ -0,0 +1,40 @@ + +SUMMARY = "OpenTelemetry Example Programs" +DESCRIPTION = "Example programs demonstrating OpenTelemetry OTLP gRPC logging in RDK Yocto environment" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" +FILESEXTRAPATHS:prepend := "${THISDIR}/opentelemetry-examples:" + +PACKAGE_ARCH = "${MIDDLEWARE_ARCH}" + +SRC_URI = "file://otlp_grpc_logging.cpp \ + file://CMakeLists.txt \ + file://otlp_logger.cpp \ + file://otlp_logger.h \ + file://test_main.cpp \ + " + +S = "${WORKDIR}" + +DEPENDS = "opentelemetry-cpp" +RDEPENDS_${PN} = "opentelemetry-cpp grpc protobuf" + +INSANE_SKIP:${PN} += "dev-deps" + +inherit cmake + +# do_install() { +# install -d ${D}${bindir} +# install -m 0755 otlp_grpc_logging ${D}${bindir}/ +# } + + +EXTRA_OECMAKE = "\ + -DBUILD_SHARED_LIBS=ON \ + -DWITH_ABI_VERSION_1=ON \ + -DWITH_ABI_VERSION_2=OFF \ + -DWITH_STL=OFF \ + -DCMAKE_CXX_STANDARD=17 \ +" + + diff --git a/recipes-support/opentelemetry/opentelemetry/0001-link-absl-strings-into-common.patch b/recipes-support/opentelemetry/opentelemetry/0001-link-absl-strings-into-common.patch new file mode 100644 index 00000000..d572b727 --- /dev/null +++ b/recipes-support/opentelemetry/opentelemetry/0001-link-absl-strings-into-common.patch @@ -0,0 +1,26 @@ + +--- a/sdk/src/common/CMakeLists.txt ++++ b/sdk/src/common/CMakeLists.txt +@@ -1,6 +1,8 @@ + # Copyright The OpenTelemetry Authors + # SPDX-License-Identifier: Apache-2.0 + ++find_package(absl CONFIG REQUIRED) ++ + set(COMMON_SRCS random.cc global_log_handler.cc env_variables.cc base64.cc + disabled.cc) + if(WIN32) +@@ -17,6 +19,16 @@ + target_link_libraries( + opentelemetry_common PUBLIC opentelemetry_api opentelemetry_sdk + Threads::Threads) ++ ++ target_link_libraries(opentelemetry_common PRIVATE ++ absl::strings absl::strings_internal ++ absl::base ++ absl::raw_logging_internal ++ absl::log_severity ++ absl::throw_delegate ++ ) ++ ++ set_target_properties(opentelemetry_common PROPERTIES LINK_FLAGS "-Wl,--no-as-needed")