Home
[RDK Central Wiki]
CMF
[Code Releases]
Overview
This document captures architecture, integration flow, macros, build steps, and troubleshooting details for OpenTelemetry integration into RDK-E Thunder plugins.
Architecture & Components
**OTLP Logger Library** (`libotlp_logger.so.1`): Wrapper over OTel C++ SDK exporting logs to OTLP gRPC endpoint.
**Thunder Plugins**: LOGINFO/LOGWARN/LOGERR redirected to OTel logger.
**OTel Collector**: Receives OTLP logs and exports to backend.
**Build System**: Yocto + CMake for library and plugins.
**Splunk Collector**: Build steps for Splunk Collector
Logging API Migration
PoC code is available here: https://github.com/rdkcentral/meta-rdk-video/pull/2292/
#define LOGINFO(...) do {otlp_logger::log_msgf(opentelemetry::logs::Severity::kInfo, "" __VA_ARGS__);}while(0)
#define LOGWARN(...) do {otlp_logger::log_msgf(opentelemetry::logs::Severity::kWarn, "" __VA_ARGS__);}while(0)
#define LOGERR(...) do {otlp_logger::log_msgf(opentelemetry::logs::Severity::kError, "" __VA_ARGS__);}while(0)
OTel Logger Library — High-Level Internal Flow
PoC code is available here: https://github.com/rdkcentral/meta-rdk/pull/423/files
The logger library follows these steps:
Initialize the library (once per program):
Create the OTLP gRPC log exporter (OtlpGrpcLogRecordExporter).
Create a log record processor using the exporter.
Create a LoggerProvider from the processor.
Set the global logger provider so all loggers use this pipeline.
Logging API at runtime:
Retrieve the logger from the global logger provider.
Call EmitLogRecord() with severity + formatted message.
This design ensures minimal overhead in plugins and centralizes all OTLP configuration in one shared library.
Build & Link (CMake)
find_package(opentelemetry-cpp CONFIG REQUIRED)
add_library(otlp_logger SHARED otlp_logger.cpp)
target_link_libraries(otlp_logger PRIVATE opentelemetry_exporter_otlp_grpc_logs opentelemetry_logs opentelemetry_common)
target_link_libraries(DisplaySettings PRIVATE otlp_logger)
target_link_libraries(DeviceInfo PRIVATE otlp_logger)
Yocto/BitBake Recipes
SOLIBS = ".so"
SOLIBSDEV = ""
FILES:${PN} += "${libdir}/*.so ${libdir}/*.so.*"
RDEPENDS:${PN} += "otlp-logger"
Ensure logger and its dependencies are present in rootfs so plugins can resolve them at runtime.
Runtime Configuration
The default configuration for the OTLP endpoint is as below:
OTEL_EXPORTER_OTLP_ENDPOINT default = http://localhost:4317
The default value can be changed with the environment variable as below:
export OTEL_EXPORTER_OTLP_ENDPOINT=grpc://<collector-ip>:4317
LD_LIBRARY_PATH=/opt/otlp_libraries2:/usr/lib
Observation
The otlp logger is integrated with the entservices plugins. These plugins send the logs at the time of starting. There are no frequent logs observed after that.
The logs are forwarded to the local splunk collector. The splunk collector was cross compiled to arm7 architecture and it was compressed to 38MB. The uncompressed binary is about 255MB.
When the compressed binary is started, it will be uncompressed first and then run. So it will take up the space of 255MB in RAM
There is no noticeable increase in CPU load, as there is not many logs from the processes.
Building Splunk Collector
The below steps are used to build the splunk collector
git clone https://github.com/signalfx/splunk-otel-collector.git
go build -o splunk-otel-collector ./cmd/otelcol # with CGO_ENABLED
CGO_ENABLED=0 go build -o splunk-otel-collector -ldflags="-s -w" ./cmd/otelcol #CGO disabled
sudo snap install upx
sudo apt-get install upx
upx --best --lzma splunk-otel-collector #compression
In STB:
mkdir /var/lib/otelcol/metrics_disk_queue
mkdir /var/lib/otelcol/logs_disk_queue
./splunk-otel-collector --config ./otel_collector_config.yaml
Troubleshooting Notes
Missing library: Use readelf -d, objdump -p.
nostd vs std mismatch: Always use std::shared_ptr inside logger.
Use LD_DEBUG=libs to inspect loader decisions
.