
{"id":9708,"date":"2022-06-21T13:53:04","date_gmt":"2022-06-21T13:53:04","guid":{"rendered":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/"},"modified":"2026-08-07T10:55:27","modified_gmt":"2026-08-07T10:55:27","slug":"logger","status":"publish","type":"page","link":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/","title":{"rendered":"RDK Logger"},"content":{"rendered":"\n<p>RDK Logger is a general-purpose logging framework for RDK middleware components across video and broadband platform stacks. It provides a unified logging interface that standardizes how RDK components generate, filter, format, and route log messages. The framework supports configurable log levels per module through a centralized configuration file, enables runtime log level changes without service restarts, and routes output to multiple destinations including console, syslog, systemd journal, and rolling files.<\/p>\n\n\n\n<p>On video platforms, RDK Logger serves as the logging backbone for middleware components such as the application manager, media pipeline, compositor, and Thunder plugin ecosystem. On broadband platforms, it fulfills the same role for protocol agents, platform management, and connectivity services. The same library binary and configuration model apply across all platform stacks, with the module naming convention (<code>LOG.RDK.&lt;MODULE&gt;<\/code>) providing the separation boundary between subsystems.<\/p>\n\n\n\n<p>RDK Logger operates as a shared library (<code>librdkloggers<\/code>) that client processes link against. It uses Log4C as its underlying backend for log routing and formatting, and exposes a compact C API centered on the <code>RDK_LOG<\/code> macro. A companion command-line utility (<code>rdklogctrl<\/code>) communicates with running processes over a local UDP socket to change log levels at runtime without requiring a restart.<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">flowchart LR\n\n%% Styles\nclassDef RDKMW stroke:#75D701,fill:#F1FFE6,stroke-width:2px\nclassDef Logger stroke:#FF6B35,fill:#FFF0EA,stroke-width:3px\nclassDef VL stroke:#808080,fill:#F2F2F2,stroke-width:2px\n\nRDKMW[\"RDK Middleware Components\"]\nRDKLogger[\"RDK Logger\"]\nSysLog[\"Log4C \/ syslog\\n\/ systemd journal\\n\/ rolling files\"]\n\nRDKMW -->|RDK_LOG APIs| RDKLogger\nRDKLogger -->|Log4C APIs| SysLog\n\nclass RDKMW RDKMW\nclass RDKLogger Logger\nclass SysLog VL<\/pre><\/div>\n\n\n\n<p><strong>Key Features &amp; Responsibilities:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Unified Logging API<\/strong>: Provides the <code>RDK_LOG(level, module, format, ...)<\/code> macro as a single, consistent logging interface used by all RDK middleware components, replacing direct use of <code>printf<\/code>, <code>fprintf<\/code>, or <code>syslog<\/code>.<\/li>\n\n\n\n<li><strong>Module-Specific Log Level Control<\/strong>: Maintains independent log level configuration per component using the <code>LOG.RDK.&lt;MODULE><\/code> naming convention. Modules not explicitly configured inherit the default level set under <code>LOG.RDK.DEFAULT<\/code>.<\/li>\n\n\n\n<li><strong>Three-Tier Configuration Override<\/strong>: Resolves the active configuration file at startup using a priority chain \u2014 <code>\/opt\/debug.ini<\/code> (highest) \u2192 <code>\/nvram\/debug.ini<\/code> \u2192 <code>\/etc\/debug.ini<\/code> (default) \u2014 enabling field-level overrides without modifying the base system image.<\/li>\n\n\n\n<li><strong>Runtime Log Level Control<\/strong>: The <code>rdklogctrl<\/code> utility sends UDP control messages to running processes on port 12035, enabling immediate log level changes per module without process restart.<\/li>\n\n\n\n<li><strong>Multiple Output Destinations<\/strong>: Supports console (<code>stdout<\/code>\/<code>stderr<\/code>), syslog daemon, systemd journal (when available), and rolling file appenders through a pluggable Log4C backend.<\/li>\n\n\n\n<li><strong>Configurable Log Formats<\/strong>: Six log message layouts are available, ranging from plain text to detailed formats including timestamps, thread IDs, module name, and log level.<\/li>\n\n\n\n<li><strong>Milestone Logging<\/strong>: Provides a dedicated <code>logMilestone()<\/code> API that records timestamped system lifecycle events (using <code>CLOCK_MONOTONIC_RAW<\/code>) to a dedicated milestones log file, separate from general component logs.<\/li>\n\n\n\n<li><strong>Onboarding Log Support<\/strong>: Writes structured onboarding events to a dedicated log path during the device provisioning phase, with suppression logic based on provisioning state flags.<\/li>\n\n\n\n<li><strong>Thread-Safe Operation<\/strong>: Uses mutex protection (<code>pthread_mutex_t<\/code>) around initialization and log message dispatch, enabling safe concurrent use from multi-threaded RDK components without external synchronization.<\/li>\n\n\n\n<li><strong>Performance-Optimized Filtering<\/strong>: Log level checks are performed before any formatting or output I\/O; when a level is disabled, the call avoids message formatting and backend writes (but still performs the mutex-protected category\/priority check and dynamic-control polling).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Design<\/h2>\n\n\n\n<p>RDK Logger follows a modular library architecture where the logging policy, output routing, and runtime control concerns are separated into distinct subsystems. The public API layer provides the <code>RDK_LOG<\/code> macro and initialization functions. A private implementation layer (<code>rdk_debug_priv.c<\/code>) handles Log4C backend integration, configuration parsing, and the actual message dispatch. A runtime control layer (<code>rdk_dynamic_logger.c<\/code>) implements a non-blocking UDP listener that processes log level change requests from the <code>rdklogctrl<\/code> utility. This separation allows the logging path to remain lightweight while control plane operations are handled independently.<\/p>\n\n\n\n<p>The design prioritizes minimal overhead on the fast logging path. Level checks are performed first, and if the level is disabled for the given module, the call returns immediately without any formatting or I\/O. Message formatting, timestamp generation, and backend dispatch only occur for messages that pass the level check. The Log4C backend manages output routing, file rotation, and integration with system logging facilities.<\/p>\n\n\n\n<p>Northbound integration is achieved through the <code>rdk_logger.h<\/code> public header and the <code>librdkloggers<\/code> shared library. Any RDK component \u2014 whether a Thunder plugin, a standalone daemon, or a user-space utility \u2014 links against this library and calls <code>RDK_LOGGER_INIT()<\/code> once before issuing log messages. The <code>RDK_LOGGER_INIT()<\/code> macro automatically resolves the correct configuration file using the three-tier priority chain.<\/p>\n\n\n\n<p>Southbound integration is handled by the Log4C library. RDK Logger registers custom layout types (formatters) and custom appender types (output backends) with Log4C before calling <code>log4c_init()<\/code>. The <code>log4crc<\/code> XML file controls how Log4C wires these layouts and appenders to log categories. This design allows the output format and destination to be changed by modifying <code>log4crc<\/code> rather than recompiling.<\/p>\n\n\n\n<p>The runtime control IPC mechanism uses a UDP socket (port 12035, loopback broadcast <code>127.255.255.255<\/code>). When <code>rdklogctrl<\/code> is invoked, it constructs a structured binary message with a <code>\"COMC\"<\/code> signature, the target process name, the module name, and the new log level, then broadcasts it. Each running process that has initialized RDK Logger maintains a non-blocking UDP socket and calls <code>rdk_dyn_log_process_pending_request()<\/code> to drain any pending control messages. The receiving side validates the signature, verifies the target process name against <code>__progname<\/code>, and applies the level change atomically.<\/p>\n\n\n\n<p>Data persistence for standard log messages is delegated to Log4C appenders configured in <code>log4crc<\/code> (e.g., console\/syslog\/journal or Log4C file\/rolling-file appenders). RDK Logger itself does not maintain a separate configuration cache beyond the Log4C category priority state applied at startup. Milestone log entries are persisted directly to a flat log file via <code>fopen<\/code>\/<code>fprintf<\/code>. Onboarding log entries are appended to a separate file path and are suppressed once the device is marked as provisioned.<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">flowchart TD\n    subgraph RDKLoggerBoundary[\"RDK Logger (librdkloggers)\"]\n\n        subgraph PublicAPI[\"Public API Layer\"]\n            API[\"rdk_logger.h\\nRDK_LOG macro\\nrdk_logger_init\"]\n        end\n\n        subgraph InitSubsystem[\"Initialization Subsystem\"]\n            Init[\"rdk_logger_init.c\\nrdk_logger_ext_init\\nrdk_logger_deinit\"]\n        end\n\n        subgraph PrivateCore[\"Private Core (rdk_debug_priv.c)\"]\n            ConfigParser[\"Configuration Parser\\nrdk_logger_parse_config\"]\n            LevelFilter[\"Level Filter\\nlog4c_category_is_priority_enabled\"]\n            Formatter[\"Format Handlers\\nformat_plaintext \/ format_with_ts\\nformat_with_tid \/ format_detail_with_ts\"]\n            Appenders[\"Appender Backends\\nto_console \/ to_syslog\\nto_journal\\nrollingfile (built-in)\"]\n        end\n\n        subgraph DynControl[\"Runtime Control (rdk_dynamic_logger.c)\"]\n            UDPListener[\"UDP Listener\\nPort 12035\\nrdk_dyn_log_process_pending_request\"]\n        end\n\n        subgraph Subsystems[\"Logging Subsystems\"]\n            Milestone[\"Milestone Logger\\nrdk_logger_milestone.c\"]\n            Onboard[\"Onboarding Logger\\nrdk_logger_onboard.c\"]\n        end\n    end\n\n    subgraph Backend[\"System Backend\"]\n        Log4C[\"Log4C Library\"]\n        SysLog[\"syslog \/ systemd journal\"]\n        FileFS[\"Rolling File (filesystem)\"]\n        Console[\"Console stdout\/stderr\"]\n    end\n\n    subgraph Control[\"Runtime Control Tool\"]\n        rdklogctrl[\"rdklogctrl utility\\nUDP port 12035\"]\n    end\n\n    API --> Init\n    Init --> ConfigParser\n    Init --> UDPListener\n    API --> LevelFilter\n    LevelFilter --> Formatter\n    Formatter --> Appenders\n    Appenders --> Log4C\n    Log4C --> Console\n    Log4C --> SysLog\n    Log4C --> FileFS\n    UDPListener --> ConfigParser\n    rdklogctrl -->|UDP broadcast| UDPListener\n    Milestone --> FileFS\n    Onboard --> FileFS<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Threading Model<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Threading Architecture<\/strong>: Multi-threaded (library \u2014 runs in the context of the client process threads)<\/li>\n\n\n\n<li><strong>Main Thread \/ Client Application Thread<\/strong>: Issues <code>RDK_LOG()<\/code> calls from arbitrary client threads. Mutex (<code>gLoggingMutex<\/code>) serializes concurrent log message dispatch through the Log4C backend.<\/li>\n\n\n\n<li><strong>Initialization Thread<\/strong>: The first caller of <code>rdk_logger_init()<\/code> acquires <code>gInitMutex<\/code> to run the one-time initialization sequence. Subsequent callers find <code>isLogInited = true<\/code> and return immediately under the same mutex.<\/li>\n\n\n\n<li><strong>UDP Control Path<\/strong>: The runtime control mechanism is non-blocking; <code>rdk_dyn_log_process_pending_request()<\/code> uses <code>select()<\/code> with a zero timeout and is called from within the client process&#8217;s own event loop or logging path. The runtime control path requires no dedicated listener thread.<\/li>\n\n\n\n<li><strong>Synchronization<\/strong>: Two <code>pthread_mutex_t<\/code> instances are used \u2014 <code>gInitMutex<\/code> guards the initialization state flag and <code>rdk_logger_ext_init<\/code> path; <code>gLoggingMutex<\/code> guards extended initialization of per-module appenders. The main logging path relies on Log4C&#8217;s own thread safety for category priority checks.<\/li>\n\n\n\n<li><strong>Async \/ Event Dispatch<\/strong>: All log messages are written synchronously within the calling thread. Runtime control updates apply immediately after <code>rdk_dbg_priv_log_reconfig()<\/code> updates the Log4C category priority.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Platform and Integration Requirements<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Build Dependencies<\/strong>: <code>log4c >= 1.2.3<\/code> (mandatory, detected via <code>PKG_CHECK_MODULES<\/code>); <code>libglib-2.0<\/code> (mandatory, linked via <code>$(GLIB_LIBS)<\/code> \/ <code>$(GLIB_CFLAGS)<\/code> provided by the build environment); <code>libsystemd >= 209<\/code> (optional, auto-detected via <code>PKG_CHECK_MODULES<\/code>; enables systemd journal appender when present).<\/li>\n\n\n\n<li><strong>Configuration Files<\/strong>: <code>\/etc\/debug.ini<\/code> must exist as the default configuration file. <code>\/opt\/debug.ini<\/code> and <code>\/nvram\/debug.ini<\/code> are optional override paths. <code>log4crc<\/code> must be installed at the location Log4C searches by default (typically <code>\/etc\/log4crc<\/code> or the path set by <code>LOG4C_RCPATH<\/code>) to configure appenders and layouts.<\/li>\n\n\n\n<li><strong>Startup Order<\/strong>: RDK Logger must be initialized before any RDK middleware component that issues <code>RDK_LOG()<\/code> calls. As a shared library, initialization occurs in-process at the time the first component calls <code>RDK_LOGGER_INIT()<\/code>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Component State Flow<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Initialization to Active State<\/h4>\n\n\n\n<p>The component transitions through the following states during its lifecycle: <strong>Initializing<\/strong> (mutex acquired, check <code>isLogInited<\/code> flag) \u2192 <strong>LoadingConfig<\/strong> (parse the selected debug.ini, populate Log4C category priorities) \u2192 <strong>InitializingBackend<\/strong> (register custom layouts and appenders, call <code>log4c_init()<\/code>) \u2192 <strong>StartingDynamicControl<\/strong> (open UDP socket on port 12035, bind to <code>127.255.255.255<\/code>) \u2192 <strong>Active<\/strong> (processing <code>RDK_LOG()<\/code> calls, servicing runtime control messages) \u2192 <strong>Shutdown<\/strong> (close UDP socket, release resources).<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant App as RDK Component \/ Application\n    participant Logger as RDK Logger (rdk_logger_init)\n    participant PrivCore as Private Core (rdk_debug_priv)\n    participant Log4C as Log4C Backend\n    participant DynLog as Dynamic Logger (rdk_dyn_log_init)\n    participant FS as File System\n\n    App->>Logger: RDK_LOGGER_INIT()\n    Note over Logger: Check \/opt\/debug.ini via access()\n    Logger->>FS: access(DEBUG_INI_OVERRIDE_PATH_1)\n    alt \/opt\/debug.ini accessible\n        FS-->>Logger: File found\n        Logger->>PrivCore: rdk_dbg_priv_config(\"\/opt\/debug.ini\")\n    else Check \/nvram\/debug.ini\n        Logger->>FS: access(DEBUG_INI_OVERRIDE_PATH_2)\n        alt \/nvram\/debug.ini accessible\n            FS-->>Logger: File found\n            Logger->>PrivCore: rdk_dbg_priv_config(\"\/nvram\/debug.ini\")\n        else Use default\n            Logger->>PrivCore: rdk_dbg_priv_config(\"\/etc\/debug.ini\")\n        end\n    end\n\n    Note over PrivCore: rdk_dbg_priv_init() - register layouts and appenders, log4c_init()\n    PrivCore->>Log4C: log4c_layout_type_set (6 layout types)\n    PrivCore->>Log4C: log4c_appender_type_set (console, syslog, journal)\n    PrivCore->>Log4C: log4c_init()\n    Log4C-->>PrivCore: Backend initialized\n    PrivCore->>FS: fopen \/ fgets debug.ini\n    FS-->>PrivCore: Module level entries\n    Note over PrivCore: Set log4c category priorities per module\n    PrivCore-->>Logger: RDK_SUCCESS\n\n    Logger->>DynLog: rdk_dyn_log_init()\n    DynLog->>DynLog: socket(AF_INET, SOCK_DGRAM) bind port 12035\n    DynLog-->>Logger: UDP listener ready\n\n    Note over Logger: isLogInited = true\n    Logger-->>App: RDK_SUCCESS (Active)\n\n    loop Runtime\n        App->>Logger: RDK_LOG(level, module, format, ...)\n        Logger->>PrivCore: rdk_dbg_priv_log_msg()\n    end\n\n    App->>Logger: rdk_logger_deinit()\n    Logger->>DynLog: rdk_dyn_log_deinit()\n    DynLog->>DynLog: close UDP socket\n    Logger-->>App: RDK_SUCCESS<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Runtime State Changes<\/h4>\n\n\n\n<p><strong>State Change Triggers:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Module Log Level Change via rdklogctrl<\/strong>: When a valid UDP control message is received matching the process name and a recognized module name, <code>rdk_dbg_priv_log_reconfig()<\/code> updates the Log4C category priority for that module immediately. Subsequent <code>RDK_LOG()<\/code> calls for that module reflect the new level without any restart.<\/li>\n\n\n\n<li><strong>Invalid Control Message<\/strong>: Messages that fail signature validation (<code>\"COMC\"<\/code> check) or have a mismatched process name are discarded; out-of-range log levels are rejected and reported to <code>stderr<\/code> by <code>rdk_dyn_log_validate_component_name()<\/code>.<\/li>\n\n\n\n<li><strong>Configuration File Not Found<\/strong>: If the selected debug.ini cannot be opened, <code>rdk_logger_parse_config()<\/code> returns <code>RDK_FAILURE<\/code>, initialization of RDK Logger fails, and <code>isLogInited<\/code> remains false. Log messages issued before a successful initialization are suppressed.<\/li>\n<\/ul>\n\n\n\n<p><strong>Context Switching Scenarios:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Three-Tier Configuration Resolution<\/strong>: At startup, <code>RDK_LOGGER_INIT()<\/code> checks <code>\/opt\/debug.ini<\/code>, then <code>\/nvram\/debug.ini<\/code>, then <code>\/etc\/debug.ini<\/code>. The first accessible file is used exclusively; the others are not merged.<\/li>\n\n\n\n<li><strong>Extended Initialization (<code>rdk_logger_ext_init<\/code>)<\/strong>: A component may call <code>rdk_logger_ext_init()<\/code> with an <code>rdk_logger_ext_config_t<\/code> structure to register a specific module name with a dedicated appender, output type, format, and file policy. This is used for components that require a separate log file rather than the shared console or syslog output.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Call Flows<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Initialization Call Flow<\/h4>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant App as RDK Component\n    participant Logger as rdk_logger_init\n    participant PrivCore as Private Core\n    participant Log4C as Log4C Backend\n    participant DynLog as rdk_dyn_log_init\n\n    App->>Logger: RDK_LOGGER_INIT() macro\n    Logger->>Logger: Acquire gInitMutex, check isLogInited\n    Logger->>PrivCore: rdk_dbg_priv_init()\n    PrivCore->>Log4C: Register 6 layout types and 3 appender types\n    PrivCore->>Log4C: log4c_init()\n    Log4C-->>PrivCore: Initialized (reads log4crc)\n    PrivCore-->>Logger: Init complete\n    Logger->>PrivCore: rdk_dbg_priv_config(configFile)\n    PrivCore->>PrivCore: fopen and parse debug.ini entries\n    PrivCore->>Log4C: log4c_category_set_priority per module\n    PrivCore-->>Logger: RDK_SUCCESS\n    Logger->>DynLog: rdk_dyn_log_init()\n    DynLog->>DynLog: socket and bind on port 12035\n    DynLog-->>Logger: Socket ready\n    Logger->>Logger: Set isLogInited true, release gInitMutex\n    Logger-->>App: RDK_SUCCESS<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Request Processing Call Flow<\/h4>\n\n\n\n<p><code>RDK_LOG()<\/code> is an alias for <code>rdk_logger_msg_printf()<\/code>. On every invocation the module and format pointer are validated before calling <code>rdk_dbg_priv_log_msg()<\/code>. Inside <code>rdk_dbg_priv_log_msg()<\/code>, the Log4C category priority check acts as the fast-path filter: if the level is not enabled for the module, the function returns without any formatting or I\/O.<\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Client as RDK Component Thread\n    participant Macro as RDK_LOG macro\n    participant MsgPrintf as rdk_logger_msg_printf\n    participant PrivLog as rdk_dbg_priv_log_msg\n    participant Log4C as Log4C Backend\n    participant Output as Output Destination\n\n    Client->>Macro: RDK_LOG(level, module, format, ...)\n    Macro->>MsgPrintf: rdk_logger_msg_printf(level, module, format, args)\n    MsgPrintf->>MsgPrintf: Validate module and format pointers\n    MsgPrintf->>PrivLog: rdk_dbg_priv_log_msg(level, module, format, args)\n    PrivLog->>Log4C: log4c_category_is_priority_enabled(category, priority)\n    alt Level enabled for module\n        Log4C-->>PrivLog: Enabled\n        PrivLog->>PrivLog: vsnprintf into format buffer\n        PrivLog->>Log4C: log4c_category_vlog(cat, log4cPriority, format, args)\n        Log4C->>Output: Write formatted message (console\/syslog\/journal\/file)\n        Output-->>Log4C: Written\n        Log4C-->>PrivLog: Done\n        PrivLog-->>MsgPrintf: Return\n        MsgPrintf-->>Client: Return\n    else Level disabled (fast path)\n        Log4C-->>PrivLog: Disabled\n        PrivLog-->>MsgPrintf: Return (no-op)\n        MsgPrintf-->>Client: Return (no-op)\n    end<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Runtime Control Call Flow<\/h4>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Admin as Operator\n    participant Ctrl as rdklogctrl utility\n    participant UDP as UDP Socket (port 12035)\n    participant Listener as rdk_dyn_log_process_pending_request\n    participant Reconfig as rdk_dbg_priv_log_reconfig\n    participant Log4C as Log4C Category\n\n    Admin->>Ctrl: rdklogctrl myapp LOG.RDK.MODULE DEBUG\n    Ctrl->>Ctrl: Validate module name prefix and log level string\n    Ctrl->>UDP: sendto(127.255.255.255:12035, COMC-framed packet)\n    Note over Listener: Called from within target process event loop\n    Listener->>UDP: select() + recvfrom() \u2014 non-blocking\n    UDP-->>Listener: Binary control packet\n    Listener->>Listener: Verify COMC signature and sender == 127.0.0.1\n    Listener->>Listener: Match __progname against app_name field\n    Listener->>Reconfig: rdk_dbg_priv_log_reconfig(\"LOG.RDK.MODULE\", RDK_LOG_DEBUG)\n    Reconfig->>Log4C: log4c_category_set_priority(cat, LOG4C_PRIORITY_DEBUG)\n    Log4C-->>Reconfig: Priority updated\n    Reconfig-->>Listener: true (success)\n    Listener->>Listener: fprintf(stderr, \"Log level change ... success\")<\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Internal Modules<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Module \/ Class<\/th><th>Description<\/th><th>Key Files<\/th><\/tr><\/thead><tbody><tr><td><code>Core Logging API<\/code><\/td><td>Exposes the <code>RDK_LOG<\/code> macro, initialization functions, and log level enumeration. Entry point for all RDK components.<\/td><td><code>include\/rdk_logger.h<\/code>, <code>include\/rdk_debug.h<\/code><\/td><\/tr><tr><td><code>Initialization Manager<\/code><\/td><td>Implements <code>rdk_logger_init()<\/code>, <code>rdk_logger_ext_init()<\/code>, and <code>rdk_logger_deinit()<\/code>. Guards one-time initialization with a mutex. Receives external data through the debug.ini file path.<\/td><td><code>src\/rdk_logger_init.c<\/code><\/td><\/tr><tr><td><code>Private Core<\/code><\/td><td>Implements Log4C backend integration, all six layout formatters, three custom appender backends (<code>to_console<\/code>, <code>to_syslog<\/code>, <code>to_journal<\/code>) plus rolling file output via Log4C&#8217;s built-in <code>rollingfile<\/code> appender, configuration file parsing (<code>rdk_logger_parse_config<\/code>), module-level log category management, and the <code>rdk_dbg_priv_log_msg<\/code> dispatch function.<\/td><td><code>src\/rdk_debug_priv.c<\/code>, <code>src\/include\/rdk_debug_priv.h<\/code><\/td><\/tr><tr><td><code>Debug Dispatch<\/code><\/td><td>Public-facing wrappers (<code>rdk_logger_msg_printf<\/code>, <code>rdk_dbg_MsgRaw<\/code>, <code>rdk_logger_msg_vsprintf<\/code>) that validate parameters and forward to <code>rdk_dbg_priv_log_msg<\/code>. Also provides <code>rdk_logger_set_logLevel<\/code>, <code>rdk_logger_enable_logLevel<\/code>, and <code>rdk_logger_level_from_string<\/code>.<\/td><td><code>src\/rdk_debug.c<\/code><\/td><\/tr><tr><td><code>Dynamic Logger<\/code><\/td><td>Implements the non-blocking UDP listener (port 12035) used for runtime log level control. Validates incoming <code>\"COMC\"<\/code>-signed messages and calls <code>rdk_dbg_priv_log_reconfig<\/code> on matched entries.<\/td><td><code>src\/rdk_dynamic_logger.c<\/code>, <code>src\/include\/rdk_dynamic_logger.h<\/code><\/td><\/tr><tr><td><code>Milestone Logger<\/code><\/td><td>Provides <code>logMilestone(msg_code)<\/code> which appends a <code>&lt;code&gt;:&lt;uptime_ms&gt;<\/code> record to the milestones log file using <code>CLOCK_MONOTONIC_RAW<\/code>. Receives external data through the <code>msg_code<\/code> string argument.<\/td><td><code>src\/rdk_logger_milestone.c<\/code>, <code>include\/rdk_logger_milestone.h<\/code><\/td><\/tr><tr><td><code>Onboarding Logger<\/code><\/td><td>Provides <code>rdk_logger_log_onboard(module, msg, ...)<\/code> for writing provisioning-phase log entries to a dedicated onboarding log file. Suppressed when <code>\/nvram\/.device_onboarded<\/code> or <code>\/nvram\/DISABLE_ONBOARD_LOGGING<\/code> exists.<\/td><td><code>src\/rdk_logger_onboard.c<\/code><\/td><\/tr><tr><td><code>Runtime Control Utility<\/code><\/td><td>CLI tool (<code>rdklogctrl<\/code>) that constructs and sends <code>\"COMC\"<\/code>-framed UDP messages to change log levels in running processes. Also includes the milestone CLI tool (<code>rdklogmilestone<\/code>) and the onboarding utility (<code>rdk_logger_onboard_main<\/code>).<\/td><td><code>utils\/rdklogctrl.c<\/code>, <code>utils\/rdklogmilestone.c<\/code>, <code>utils\/rdk_logger_onboard_main.c<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Component Interactions<\/h2>\n\n\n\n<p>RDK Logger is a foundational library where all interactions flow inward \u2014 middleware components call into RDK Logger, and RDK Logger calls down into system libraries.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Interaction Matrix<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Target Component \/ Layer<\/th><th>Interaction Purpose<\/th><th>Key APIs \/ Topics<\/th><\/tr><\/thead><tbody><tr><td><strong>System &amp; Platform Layers<\/strong><\/td><td><\/td><td><\/td><\/tr><tr><td>Log4C Library<\/td><td>Backend log message formatting, routing, and file management<\/td><td><code>log4c_init()<\/code>, <code>log4c_category_get()<\/code>, <code>log4c_category_set_priority()<\/code>, <code>log4c_category_log()<\/code><\/td><\/tr><tr><td>syslog daemon<\/td><td>System-wide log integration<\/td><td><code>openlog()<\/code>, <code>syslog()<\/code>, <code>closelog()<\/code> \u2014 active when <code>HAVE_SYSLOG_H<\/code> is defined<\/td><\/tr><tr><td>systemd journal<\/td><td>Modern Linux logging integration<\/td><td><code>sd_journal_print()<\/code> \u2014 active when <code>HAVE_SYSTEMD<\/code> is defined and <code>libsystemd &gt;= 209<\/code> is present<\/td><\/tr><tr><td>File system<\/td><td>Configuration file parsing; milestone and onboarding log persistence<\/td><td><code>fopen()<\/code>, <code>fgets()<\/code>, <code>fprintf()<\/code> on <code>\/etc\/debug.ini<\/code>, <code>\/opt\/debug.ini<\/code>, <code>\/nvram\/debug.ini<\/code>, milestone log, onboarding log<\/td><\/tr><tr><td>UDP socket (loopback)<\/td><td>Runtime log level control from <code>rdklogctrl<\/code><\/td><td><code>socket(AF_INET, SOCK_DGRAM)<\/code>, port 12035, <code>127.255.255.255<\/code> broadcast<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Events Published<\/h3>\n\n\n\n<p>RDK Logger operates as a logging service, receiving log messages and control commands from RDK components and routing output to configured destinations. The table below captures the operational signals it emits.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Signal<\/th><th>Destination<\/th><th>Trigger Condition<\/th><\/tr><\/thead><tbody><tr><td>Log level change acknowledgment<\/td><td><code>stderr<\/code> of the target process<\/td><td>Valid <code>rdklogctrl<\/code> message received and applied successfully<\/td><\/tr><tr><td>Milestone record<\/td><td><code>\/opt\/logs\/rdk_milestones.log<\/code> or <code>\/rdklogs\/logs\/rdk_milestones.log<\/code><\/td><td><code>logMilestone()<\/code> called by any component<\/td><\/tr><tr><td>Onboarding record<\/td><td><code>\/rdklogs\/logs\/OnBoardingLog.txt.0<\/code><\/td><td><code>rdk_logger_log_onboard()<\/code> called before device provisioning is complete<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">IPC Flow Patterns<\/h3>\n\n\n\n<p><strong>Primary Logging Flow:<\/strong><\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Component as RDK Component Thread\n    participant Logger as RDK Logger Library\n    participant Log4C as Log4C Backend\n    participant Dest as Output (console\/syslog\/journal\/file)\n\n    Component->>Logger: RDK_LOG(level, module, format, ...)\n    Logger->>Logger: Validate module and format pointers\n    Logger->>Log4C: Check priority enabled for module category\n    alt Level passes filter\n        Logger->>Logger: Format message (timestamp, module, level, TID)\n        Logger->>Log4C: log4c_category_vlog(category, priority, msg)\n        Log4C->>Dest: Write formatted record\n        Dest-->>Log4C: Written\n        Log4C-->>Logger: Complete\n        Logger-->>Component: Return\n    else Level filtered\n        Logger-->>Component: No-op return\n    end<\/pre><\/div>\n\n\n\n<p><strong>Runtime Control Flow:<\/strong><\/p>\n\n\n\n<div class=\"wp-block-merpress-mermaidjs diagram-source-mermaid\"><pre class=\"mermaid\">sequenceDiagram\n    participant Operator as Operator\n    participant Tool as rdklogctrl\n    participant Target as Target Process (RDK Logger UDP listener)\n\n    Operator->>Tool: rdklogctrl &lt;process> LOG.RDK.&lt;MODULE> &lt;LEVEL>\n    Tool->>Tool: Validate module prefix and level string\n    Tool->>Target: UDP packet to 127.255.255.255:12035\n    Note over Target: rdk_dyn_log_process_pending_request() polled by process\n    Target->>Target: Verify COMC signature, sender IP, process name\n    Target->>Target: rdk_dbg_priv_log_reconfig(module, level)\n    Target->>Target: Log4C category priority updated immediately\n    Target-->>Tool: (stderr confirmation in target process)<\/pre><\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Implementation Details<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Key Implementation Logic<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Initialization and Lifecycle Management<\/strong>: <code>rdk_logger_init()<\/code> in <code>src\/rdk_logger_init.c<\/code> serializes initialization using <code>gInitMutex<\/code> and the <code>isLogInited<\/code> flag to ensure idempotent behavior in multi-threaded environments. The initialization sequence calls <code>rdk_dbg_priv_init()<\/code> to register layout and appender types with Log4C and invoke <code>log4c_init()<\/code>, then calls <code>rdk_dbg_priv_config()<\/code> to parse the debug.ini file and set category priorities, then <code>rdk_dyn_log_init()<\/code> to open the UDP control socket.<\/li>\n\n\n\n<li><strong>Configuration Parsing<\/strong>: <code>rdk_logger_parse_config()<\/code> in <code>src\/rdk_debug_priv.c<\/code> reads the debug.ini file line-by-line, skipping comments and lines without <code>=<\/code>. For the <code>LOG.RDK.DEFAULT<\/code> entry it sets the root <code>LOG.RDK<\/code> category priority; for all other <code>LOG.RDK.*<\/code> entries it calls <code>log4c_category_get()<\/code> and <code>log4c_category_set_priority()<\/code>. Whitespace trimming is applied to both name and value tokens before comparison. Level strings are parsed case-insensitively by <code>rdk_logger_level_from_string()<\/code>.<\/li>\n\n\n\n<li><strong>Log4C Layout and Appender Registration<\/strong>: Six layout types (<code>format_plaintext<\/code>, <code>format_with_ts<\/code>, <code>format_with_tid<\/code>, <code>format_with_ts_tid<\/code>, <code>format_detail_with_ts<\/code>, <code>format_detail_without_ts<\/code>) and three custom appender types (<code>to_console<\/code>, <code>to_syslog<\/code>, <code>to_journal<\/code>) are registered in <code>rdk_dbg_priv_init()<\/code> before <code>log4c_init()<\/code> is called, so that the <code>log4crc<\/code> XML configuration file can reference them by name. Rolling file output uses Log4C&#8217;s built-in <code>rollingfile<\/code> appender type (referenced by name string via <code>log4c_appender_type_get(\"rollingfile\")<\/code>) \u2014 it is not registered as a custom type. A legacy <code>comcast_dated<\/code> layout alias is also registered for backward compatibility.<\/li>\n\n\n\n<li><strong>Extended Initialization and File Logging<\/strong>: <code>rdk_logger_ext_init()<\/code> accepts an <code>rdk_logger_ext_config_t<\/code> structure specifying a module name, log level, output type (<code>RDKLOG_OUTPUT_CONSOLE<\/code>, <code>RDKLOG_OUTPUT_SYSLOG<\/code>, <code>RDKLOG_OUTPUT_JOURNAL<\/code>, or <code>RDKLOG_OUTPUT_FILE<\/code>), format type, and an optional <code>rdk_LogOutput_File<\/code> file policy. When <code>RDKLOG_OUTPUT_FILE<\/code> is selected, the <code>rdk_LogOutput_File<\/code> structure must be populated with <code>fileName<\/code> (log file prefix, max 64 chars), <code>fileLocation<\/code> (directory path, max 256 chars), <code>fileCountMax<\/code> (maximum number of rotating files), and <code>fileSizeMax<\/code> (maximum size per file in bytes). This path, implemented in <code>rdk_dbg_priv_ext_init()<\/code>, creates or retrieves a Log4C category and attaches a dedicated <code>rollingfile<\/code> appender with a <code>sizewin<\/code> rolling policy. File rolling closes the current appender before reconfiguring, preventing data loss. This mechanism is the primary means for components that require per-component log files on disk rather than shared console or system log output.<\/li>\n\n\n\n<li><strong>Runtime Log Level Control<\/strong>: <code>rdk_dyn_log_process_pending_request()<\/code> in <code>src\/rdk_dynamic_logger.c<\/code> uses a non-blocking <code>select()<\/code> call on the UDP socket to drain any pending control messages in a loop. Each message is validated for the <code>\"COMC\"<\/code> signature and loopback source address before <code>rdk_dyn_log_validate_component_name()<\/code> matches the target process name against <code>__progname<\/code>. Validated messages invoke <code>rdk_dbg_priv_log_reconfig()<\/code> which calls <code>log4c_category_set_priority()<\/code> with the new level.<\/li>\n\n\n\n<li><strong>Error Handling Strategy<\/strong>: If configuration file parsing fails, <code>rdk_logger_init()<\/code> returns <code>RDK_FAILURE<\/code> and writes a diagnostic message to <code>printf<\/code>. When <code>log4c_init()<\/code> encounters an error, <code>rdk_dbg_priv_init()<\/code> writes a diagnostic message to <code>stderr<\/code> and the process continues with category state unchanged. When the UDP socket cannot be bound, <code>rdk_dyn_log_init()<\/code> writes a diagnostic to <code>stderr<\/code> and the process continues with static log levels only. Onboarding log file write failures produce output on <code>printf<\/code> as a fallback.<\/li>\n\n\n\n<li><strong>Logging &amp; Diagnostics<\/strong>: All <code>RDK_LOG()<\/code> calls use the <code>LOG.RDK.&lt;MODULE><\/code> naming convention. The root category <code>LOG.RDK<\/code> acts as the default parent for any module not explicitly listed in <code>debug.ini<\/code>. RDK Logger itself writes internal diagnostic messages to <code>stderr<\/code> (not through the <code>RDK_LOG<\/code> path) to avoid recursion during initialization or error conditions.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Configuration<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Key Configuration Files<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Configuration File<\/th><th>Purpose<\/th><th>Override Mechanism<\/th><\/tr><\/thead><tbody><tr><td><code>\/etc\/debug.ini<\/code><\/td><td>Default system-wide log level configuration for all <code>LOG.RDK.*<\/code> modules. Installed by the build system (<code>sysconf_DATA<\/code> in <code>Makefile.am<\/code>).<\/td><td>Overridden at runtime by <code>\/opt\/debug.ini<\/code> (highest priority) or <code>\/nvram\/debug.ini<\/code> (second priority) when either file is accessible.<\/td><\/tr><tr><td><code>\/opt\/debug.ini<\/code><\/td><td>Platform-specific or field override configuration. Takes highest priority in the <code>RDK_LOGGER_INIT()<\/code> resolution chain.<\/td><td>Takes precedence over all other configuration files when present and readable.<\/td><\/tr><tr><td><code>\/nvram\/debug.ini<\/code><\/td><td>Runtime-writable override for temporary or persistent log level changes that survive reboots. Checked when <code>\/opt\/debug.ini<\/code> is not present.<\/td><td>Overridden by <code>\/opt\/debug.ini<\/code> when present.<\/td><\/tr><tr><td><code>log4crc<\/code><\/td><td>Log4C XML configuration file. Defines layout types, appender types, and category-to-appender bindings. Installed by the build system.<\/td><td>Log4C environment variable <code>LOG4C_RCPATH<\/code> may redirect to an alternate file.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Key Configuration Parameters<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Parameter<\/th><th>Type<\/th><th>Default<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>LOG.RDK.DEFAULT<\/code><\/td><td>string (log level)<\/td><td><code>INFO<\/code> (per <code>debug.ini<\/code>)<\/td><td>Sets the log level for the root <code>LOG.RDK<\/code> category. All modules not explicitly listed in <code>debug.ini<\/code> inherit this level.<\/td><\/tr><tr><td><code>LOG.RDK.&lt;MODULE&gt;<\/code><\/td><td>string (log level)<\/td><td>Inherits <code>LOG.RDK.DEFAULT<\/code><\/td><td>Sets the log level for a specific named module. Accepted values: <code>FATAL<\/code>, <code>ERROR<\/code>, <code>WARNING<\/code>, <code>NOTICE<\/code>, <code>INFO<\/code>, <code>DEBUG<\/code>, <code>TRACE<\/code>, <code>NONE<\/code>.<\/td><\/tr><tr><td><code>DEBUG_CONF_FILE<\/code><\/td><td>compile-time string<\/td><td><code>\"debug.ini\"<\/code><\/td><td>Fallback configuration file name used when <code>rdk_logger_init()<\/code> receives a <code>NULL<\/code> path argument. Set via <code>-DDEBUG_CONF_FILE<\/code> in <code>librdkloggers_la_CFLAGS<\/code>.<\/td><\/tr><tr><td><code>LOGMILESTONE<\/code><\/td><td>compile-time flag<\/td><td>Undefined (uses <code>\/rdklogs\/logs\/<\/code>)<\/td><td>When defined at build time, milestone events are written to <code>\/opt\/logs\/rdk_milestones.log<\/code> instead of <code>\/rdklogs\/logs\/rdk_milestones.log<\/code>.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">File Output Configuration<\/h3>\n\n\n\n<p>Components that require output to rolling log files on disk use <code>rdk_logger_ext_init()<\/code> with <code>RDKLOG_OUTPUT_FILE<\/code> and populate an <code>rdk_LogOutput_File<\/code> structure passed via the <code>pFilePolicy<\/code> field of <code>rdk_logger_ext_config_t<\/code>:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Field<\/th><th>Type<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>fileName<\/code><\/td><td><code>char[64]<\/code><\/td><td>Log file name prefix. The <code>rollingfile<\/code> appender appends a numeric suffix when rotating.<\/td><\/tr><tr><td><code>fileLocation<\/code><\/td><td><code>char[256]<\/code><\/td><td>Directory path where log files are written (e.g., <code>\/rdklogs\/logs\/<\/code>).<\/td><\/tr><tr><td><code>fileCountMax<\/code><\/td><td><code>int8_t<\/code><\/td><td>Maximum number of rotating log files to retain. When 0, no size-based rotation policy is applied.<\/td><\/tr><tr><td><code>fileSizeMax<\/code><\/td><td><code>int64_t<\/code><\/td><td>Maximum size in bytes per file before rotation. When 0 with a non-zero <code>fileCountMax<\/code>, the default Log4C rolling size is used.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Passing a <code>NULL<\/code> <code>pFilePolicy<\/code> when <code>RDKLOG_OUTPUT_FILE<\/code> is selected causes <code>rdk_dbg_priv_ext_init()<\/code> to reject the configuration and write a diagnostic to <code>stderr<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Runtime Configuration<\/h3>\n\n\n\n<p>Log levels for individual modules can be changed at runtime using the <code>rdklogctrl<\/code> utility:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Change log level for a module in a running process\nrdklogctrl &lt;process_name> &lt;module_name> &lt;log_level>\n\n# Examples\nrdklogctrl myapp LOG.RDK.NETWORK DEBUG\nrdklogctrl mediaPlayer LOG.RDK.AAMP TRACE\nrdklogctrl wpeProcess LOG.RDK.THUNDER INFO\n\n# Disable all logging for a module\nrdklogctrl myapp LOG.RDK.NETWORK NONE\n\n# Available levels: FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE, NONE<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Configuration Persistence<\/h3>\n\n\n\n<p>Runtime log level changes applied through <code>rdklogctrl<\/code> are in-memory only and are lost when the target process restarts. To persist a level change across restarts, the <code>debug.ini<\/code> file at <code>\/nvram\/debug.ini<\/code> or <code>\/opt\/debug.ini<\/code> must be updated directly, as RDK Logger reads configuration only at initialization time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>RDK Logger is a general-purpose logging framework for RDK middleware components across video and broadband [&hellip;]<\/p>\n","protected":false},"author":28,"featured_media":0,"parent":9575,"menu_order":23,"comment_status":"open","ping_status":"closed","template":"","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"class_list":["post-9708","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>RDK Logger - RDK Documentation Portal | Documentation<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"RDK Logger - RDK Documentation Portal | Documentation\" \/>\n<meta property=\"og:description\" content=\"RDK Logger is a general-purpose logging framework for RDK middleware components across video and broadband [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/\" \/>\n<meta property=\"og:site_name\" content=\"RDK Documentation Portal | Documentation\" \/>\n<meta property=\"article:modified_time\" content=\"2026-08-07T10:55:27+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/\",\"url\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/\",\"name\":\"RDK Logger - RDK Documentation Portal | Documentation\",\"isPartOf\":{\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/#website\"},\"datePublished\":\"2022-06-21T13:53:04+00:00\",\"dateModified\":\"2026-08-07T10:55:27+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/developer.rdkcentral.com\/documentation\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Documentation\",\"item\":\"https:\/\/developer.rdkcentral.com\/documentation\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"RDK Broadband\",\"item\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Components\",\"item\":\"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/\"},{\"@type\":\"ListItem\",\"position\":5,\"name\":\"RDK Logger\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/developer.rdkcentral.com\/documentation\/#website\",\"url\":\"https:\/\/developer.rdkcentral.com\/documentation\/\",\"name\":\"RDK Documentation Portal | Documentation\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/developer.rdkcentral.com\/documentation\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"RDK Logger - RDK Documentation Portal | Documentation","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/","og_locale":"en_US","og_type":"article","og_title":"RDK Logger - RDK Documentation Portal | Documentation","og_description":"RDK Logger is a general-purpose logging framework for RDK middleware components across video and broadband [&hellip;]","og_url":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/","og_site_name":"RDK Documentation Portal | Documentation","article_modified_time":"2026-08-07T10:55:27+00:00","twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/","url":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/","name":"RDK Logger - RDK Documentation Portal | Documentation","isPartOf":{"@id":"https:\/\/developer.rdkcentral.com\/documentation\/#website"},"datePublished":"2022-06-21T13:53:04+00:00","dateModified":"2026-08-07T10:55:27+00:00","breadcrumb":{"@id":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/logger\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/developer.rdkcentral.com\/documentation\/"},{"@type":"ListItem","position":2,"name":"Documentation","item":"https:\/\/developer.rdkcentral.com\/documentation\/"},{"@type":"ListItem","position":3,"name":"RDK Broadband","item":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/"},{"@type":"ListItem","position":4,"name":"Components","item":"https:\/\/developer.rdkcentral.com\/documentation\/documentation\/rdk_broadband_documentation\/components\/"},{"@type":"ListItem","position":5,"name":"RDK Logger"}]},{"@type":"WebSite","@id":"https:\/\/developer.rdkcentral.com\/documentation\/#website","url":"https:\/\/developer.rdkcentral.com\/documentation\/","name":"RDK Documentation Portal | Documentation","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/developer.rdkcentral.com\/documentation\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages\/9708","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/users\/28"}],"replies":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/comments?post=9708"}],"version-history":[{"count":2,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages\/9708\/revisions"}],"predecessor-version":[{"id":13010,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages\/9708\/revisions\/13010"}],"up":[{"embeddable":true,"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/pages\/9575"}],"wp:attachment":[{"href":"https:\/\/developer.rdkcentral.com\/documentation\/wp-json\/wp\/v2\/media?parent=9708"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}