From 06bfdfa638b6e6ceabde985b9b50d8a435c935bb Mon Sep 17 00:00:00 2001 From: rdkcmf Date: Tue, 24 Jun 2025 15:07:37 +0100 Subject: [PATCH 01/37] Deploy cla action --- .github/workflows/cla.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/cla.yml diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 0000000..0550479 --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,13 @@ +name: "CLA" +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened,closed,synchronize] + +jobs: + CLA-Lite: + name: "Signature" + uses: rdkcentral/cmf-actions/.github/workflows/cla.yml@main + secrets: + PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_ASSISTANT }} \ No newline at end of file From f3f31b18fefb8a438ae9c763e69898adfe46aa64 Mon Sep 17 00:00:00 2001 From: Abhinavpv28 <162570454+Abhinavpv28@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:41:36 +0530 Subject: [PATCH 02/37] Update debug.ini (#18) --- debug.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/debug.ini b/debug.ini index 5662cc0..f800a1d 100644 --- a/debug.ini +++ b/debug.ini @@ -144,6 +144,7 @@ LOG.RDK.DHCP = ALL FATAL ERROR WARNING NOTICE INFO DEBUG LOG.RDK.T2 = ALL FATAL ERROR WARNING NOTICE INFO LOG.RDK.MEDIAPIPE = ALL ERROR WARNING INFO LOG.RDK.FWUPG = ALL FATAL ERROR WARNING NOTICE INFO +LOG.RDK.COMMONUTILITIES = ALL FATAL ERROR WARNING NOTICE INFO LOG.RDK.REMOTEDEBUGGER = ALL FATAL WARNING NOTICE INFO DEBUG ERROR LOG.RDK.RDKCPROVIDER = ALL ERROR WARNING INFO LOG.RDK.WANCNCTVTYCHK = FATAL ERROR WARNING NOTICE INFO From e1980c5bf2523f9ca17b2ebdbe3a445732205d1e Mon Sep 17 00:00:00 2001 From: Saranya2421 Date: Fri, 25 Jul 2025 15:15:24 +0530 Subject: [PATCH 03/37] RDKEMW-4794 : RDM Prints incorrect message for Codebig Path (#13) Co-authored-by: Saranya Co-authored-by: nhanasi --- debug.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug.ini b/debug.ini index f800a1d..5263438 100644 --- a/debug.ini +++ b/debug.ini @@ -154,7 +154,7 @@ LOG.RDK.RFCAPI = ALL FATAL ERROR WARNING NOTICE INFO LOG.RDK.FLASHAPP = ALL FATAL ERROR WARNING INFO LOG.RDK.DCM = ALL FATAL ERROR WARNING NOTICE INFO LOG.RDK.RDKSSACERTCHECK = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RDM = ALL FATAL ERROR WARNING NOTICE INFO +LOG.RDK.RDMAGENT = ALL FATAL ERROR WARNING NOTICE INFO LOG.RDK.LXY = FATAL ERROR WARNING NOTICE INFO LOG.RDK.IPCONTROL = ALL FATAL ERROR WARNING NOTICE INFO LOG.RDK.RDKSSADAEMON = ERROR WARNING From 59e48d37f8e41b2b1486bae329e2c0e374427c07 Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Wed, 6 Aug 2025 08:47:42 +0530 Subject: [PATCH 04/37] RDKEMW-6709: RDKLogger - Refactoring (#19) Reason for change: Refactor the RDKLogger component in such a way that, 1. The config file debug.ini is only for the override; 2. Must log even if new module not present in debug.ini 3. The config file must say only the specific level; not individual log levels 4. Default loglevel must be based on LOG.RDK.DEFAULT 5. Remove log4crc overrides Test Procedure: Tested and verified Risks: Medium Signed-off-by: dshett549 Signed-off-by: Karunakaran A Co-authored-by: Karunakaran A <48997923+karuna2git@users.noreply.github.com> --- README.md | 38 +- build.sh | 108 ----- debug.ini | 168 +------- debug.ini.sample | 33 ++ include/Makefile.am | 2 +- include/rdk_debug.h | 153 ++++--- log4crc | 177 +------- rdkb_debug.ini | 98 ----- rdkb_debug_arm.ini | 58 --- rdkb_debug_atom.ini | 43 -- rdkb_log4crc | 517 ----------------------- rdkb_log4crc_arm | 312 -------------- rdkb_log4crc_atom | 220 ---------- rdkc_log4crc | 196 --------- src/include/rdk_debug_priv.h | 51 +-- src/include/rdk_dynamic_logger.h | 8 +- {include => src/include}/rdk_utils.h | 6 +- src/rdk_debug.c | 114 ++---- src/rdk_debug_priv.c | 587 ++++++++++----------------- src/rdk_dynamic_logger.c | 34 +- src/rdk_logger_init.c | 37 +- src/rdk_logger_util.c | 56 ++- unittests/rdkIsDbgEnabled.cpp | 4 +- utils/rdklogctrl.c | 32 +- 24 files changed, 522 insertions(+), 2530 deletions(-) delete mode 100755 build.sh create mode 100644 debug.ini.sample delete mode 100644 rdkb_debug.ini delete mode 100644 rdkb_debug_arm.ini delete mode 100644 rdkb_debug_atom.ini delete mode 100644 rdkb_log4crc delete mode 100644 rdkb_log4crc_arm delete mode 100644 rdkb_log4crc_atom delete mode 100644 rdkc_log4crc rename {include => src/include}/rdk_utils.h (88%) diff --git a/README.md b/README.md index 29d49bb..43ab6ec 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,36 @@ -Overview: ---------- +# RDK Logger -The rdklogger is a general-purpose logging mechanism that utilizes log4c for formatting and supports multiple log levels and modules. The log level for each module is read from a configuration file (debug.ini, typically located at /etc/debug.ini) at startup, where log modules and their enabled log levels are defined. +RDK Logger is a general-purpose logging mechanism for RDK components. It supports multiple log levels and modules, with log levels configured via a configuration file (`debug.ini`). Each module can have its own log level, and these can be changed at runtime using the provided CLI utility. -rdklogger supports overriding the configuration at runtime by providing a persistent path to files like /opt/debug.ini or /nvram/debug.ini. It includes a CLI utility called rdklogctrl, which is used to dynamically change log levels for modules at runtime. +## Features -Internally, rdklogger leverages log4c for its formatting, log writing, and log rotation capabilities. One unique feature of rdklogger is that you do not set a single severity level above which no logs with greater severity would be logged. Instead, each level (ERROR, WARN, INFO, DEBUG, etc.) can be independently enabled or disabled. This means you could, for example, disable all ERROR logs while enabling all DEBUG logs. +- Abstracts logging client from underlying logging utility. +- Dynamically enables/disables logging level at run time. +- Provides a structured log format including timestamp, module name, log level, and message. +- Controls log level independently for each component/module. +- Enables logging globally via a single configuration value. +- Controls initial log level for each component/module from configuration file (`debug.ini`) at startup. +- Prints formatted data to stdout or log files. +- Supports separate log files for each module if configured. + +## Configuration + +Logging levels and modules are configured in `debug.ini`. If a module is not explicitly configured in `debug.ini`, it inherits the log level from `LOG.RDK.DEFAULT`. + +See `debug.ini.sample` for an example configuration file. +The sample file includes comments explaining how to set log levels for each module and what each log level enables. + +For example: +``` +LOG.RDK.DEFAULT=WARNING +LOG.RDK.FOO=DEBUG +LOG.RDK.BAR=NONE +``` + +- The component `FOO` will print DEBUG, INFO, WARNING, ERROR, and FATAL messages +- The component `BAR` prints `nothing` +- All the other components prints WARNING and higher log levels like ERROR, and FATAL as defined by `DEFAULT` + +## Runtime Control + +Use the `rdklogctrl` utility to change log levels for modules at run time. diff --git a/build.sh b/build.sh deleted file mode 100755 index 5cbcf10..0000000 --- a/build.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/sh -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -# -PWD=`pwd` -export RDK_DIR=`echo $PWD/..` -source soc/build/soc_env.sh - - -copyLibs=0 -instalLibs=0 -setupSDK=0 -buildMode="build" -instaldir=build - -for option in $@ -do - echo option = $option - if [ "$option" = "clean" ]; then - buildMode="clean" - elif [ "$option" = "install" -o "$option" = "instal" ] ; then - instalLibs=1 - elif [ "$option" = "copy" ] ; then - copyLibs=1 - elif [ "$option" = "setup" ] ; then - setupSDK=1 - fi - - -done - -if [ $setupSDK -eq 1 ]; -then - echo $PLATFORM_SDK - if [ -d "$PLATFORM_SDK" ] - then - echo "toolchain is already installed..." - else - echo Installing toolchain, it may take few seconds depends on your system - tar zxf $RDK_DIR/sdk/toolchain/staging_dir.tgz -C $RDK_DIR/sdk/toolchain - echo "toolchain installed $PLATFORM_SDK" - fi - - echo $ROOTFS - if [ -d "$ROOTFS" ] - then - echo "ROOT FS is already extracted..." - else - echo extracting ROOT FS, it may take few seconds depends on your system - sudo tar zxf $RDK_DIR/sdk/fsroot/fsroot.tgz -C $RDK_DIR/sdk/fsroot - sudo tar zxf $RDK_DIR/sdk/fsroot/curl.tgz -C $RDK_DIR/sdk/fsroot - sudo tar zxf $RDK_DIR/sdk/fsroot/mafLib.tgz -C $RDK_DIR/sdk/fsroot - echo "ROOT FS is extracted $ROOTFS" - fi - -fi - -if [ "$buildMode" = "clean" ]; -then - echo "Cleaning the build and $instaldir" - make clean -fi - -if [ $copyLibs -ne 1 ] ; -then - echo ========================================================================================================================================================= - echo --------------------------BUILDING RDK LOGGER --------------------------------- - echo ========================================================================================================================================================= - make - if [ $? -ne 0 ] ; - then - echo RDK LOGGER build failed - exit -1 - fi - echo ======================================================================================================================================================== - echo --------------------------BUILDING RDK LOGGER DONE --------------------------------- - echo ======================================================================================================================================================== -fi - -if [ $instalLibs -eq 1 ]; -then - echo installing binaries.... - mkdir -p $instaldir/env - mkdir -p $ROOTFS/mnt/nfs/env - mkdir -p $ROOTFS/mnt/nfs/lib - - cp *.ini $instaldir/env - cp log4crc $instaldir/env - cp -a $instaldir/env/* $ROOTFS/mnt/nfs/env - mkdir -p $ROOTFS/usr/lib - cp -a $instaldir/lib/* $ROOTFS/usr/lib -fi diff --git a/debug.ini b/debug.ini index 5263438..3a6d8e6 100644 --- a/debug.ini +++ b/debug.ini @@ -1,167 +1 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#### Logging #### - -EnableMPELog = TRUE - -SEPARATE.LOGFILE.SUPPORT=FALSE -LOG.RDK.DEFAULT = ERROR -LOG.RDK.TARGET = FATAL ERROR WARNING INFO -LOG.RDK.CC = FATAL ERROR WARNING INFO -LOG.RDK.CDL = FATAL ERROR WARNING INFO -LOG.RDK.SNMP = FATAL ERROR WARNING INFO -LOG.RDK.COND = NONE -LOG.RDK.DBG = NONE -LOG.RDK.DIRECTFB = NONE -LOG.RDK.DISP = FATAL ERROR INFO -LOG.RDK.DLL = NONE -LOG.RDK.DVR = FATAL ERROR WARNING INFO -LOG.RDK.REC = FATAL ERROR WARNING INFO -LOG.RDK.RBI = FATAL ERROR WARNING INFO -LOG.RDK.HN = FATAL ERROR INFO WARNING -LOG.RDK.GSTREAMER=ALL FATAL ERROR WARNING INFO DEBUG -LOG.RDK.HNSRC=ALL TRACE DEBUG FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MPSINK=ALL TRACE DEBUG FATAL ERROR WARNING NOTICE INFO -LOG.RDK.EVENT = FATAL ERROR -LOG.RDK.ED = NONE -LOG.RDK.FILESYS = FATAL ERROR WARNING INFO -LOG.RDK.FILTER = ERROR -LOG.RDK.FP = ALL INFO -LOG.RDK.GFX = ERROR -LOG.RDK.JAVA = ALL !INFO !DEBUG WARNING -LOG.RDK.JNI = !DEBUG !INFO WARNING ERROR TRACE -LOG.RDK.JVM = ALL INFO -LOG.RDK.MEDIA = FATAL ERROR WARNING INFO -LOG.RDK.MEM = NONE -LOG.RDK.MUTEX = NONE -LOG.RDK.NET = NONE -LOG.RDK.OS = FATAL ERROR WARNING -LOG.RDK.POD = FATAL ERROR WARNING INFO -LOG.RDK.SI = FATAL ERROR WARNING -LOG.RDK.INBSI = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.STORAGE = NONE -LOG.RDK.SYS = FATAL ERROR WARNING INFO -LOG.RDK.TEST = ALL DEBUG -LOG.RDK.THREAD = NONE -LOG.RDK.UTIL = NONE -LOG.RDK.UI = NONE -LOG.RDK.QAMSRC = ALL FATAL ERROR WARNING INFO -LOG.RDK.VODSRC = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MS = ALL FATAL ERROR WARNING INFO -LOG.RDK.GSTQAM = ALL FATAL ERROR WARNING INFO -LOG.RDK.IPPV = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.IPC = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PXYSRVC = FATAL ERROR WARNING INFO -LOG.RDK.RMFBASE = FATAL ERROR WARNING INFO -LOG.RDK.RDKBROWSER2 = FATAL ERROR WARNING INFO -LOG.RDK.TRM = NONE -LOG.RDK.IARMBUS = ALL DEBUG -LOG.RDK.DSMGR = ALL FATAL ERROR WARNING INFO !DEBUG -LOG.RDK.IRMGR = ALL DEBUG -LOG.RDK.MFRMGR = ALL DEBUG -LOG.RDK.POWERMGR = DEBUG -LOG.RDK.SYSMGR = ALL DEBUG -LOG.RDK.TR69MGR = ALL DEBUG -LOG.RDK.VREXMGR = ALL DEBUG -LOG.RDK.TRH = FATAL ERROR WARNING INFO -LOG.RDK.SDVAGENT = FATAL ERROR WARNING INFO -LOG.RDK.RF4CEMGR = FATAL ERROR WARNING INFO -LOG.RDK.LPRFSERVER = FATAL ERROR WARNING INFO -LOG.RDK.CEF = ALL FATAL ERROR WARNING NOTICE INFO DEBUG -LOG.RDK.WIFIWPA = ERROR WARNING INFO DEBUG -LOG.RDK.WIFIP2PWPA = ERROR WARNING INFO -LOG.RDK.NETSRVMGR = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WIFIHAL = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBPAVIDEO = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TR69HOSTIF = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.PARODUS = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.PARODUSIF = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.BTRMGR = ALL ERROR WARNING INFO -LOG.RDK.BTRCORE = ALL ERROR WARNING INFO -LOG.RDK.BTRLEMGR = ALL DEBUG FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CVR=ALL ERROR WARNING INFO -LOG.RDK.CVRUPLOAD=ALL ERROR WARNING INFO -LOG.RDK.CVRPOLL=ALL ERROR WARNING INFO -LOG.RDK.THUMBNAILUPLOAD=ALL ERROR WARNING INFO -LOG.RDK.SMARTTHUMBNAIL=ALL ERROR WARNING INFO -LOG.RDK.RMS=ALL ERROR WARNING INFO -LOG.RDK.METRICS=ALL ERROR WARNING INFO -LOG.RDK.PLUGINS=ALL ERROR WARNING INFO -LOG.RDK.WEBPA=ALL ERROR WARNING INFO -LOG.RDK.BINDING=ALL ERROR WARNING INFO -LOG.RDK.WRTC=ALL ERROR WARNING INFO -LOG.RDK.VIDEOANALYTICS=ALL ERROR WARNING INFO -LOG.RDK.AUDIOANALYTICS=ALL ERROR WARNING INFO -LOG.RDK.STORAGEMGR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.OVERLAY =ALL ERROR WARNING INFO -LOG.RDK.HTTPCLIENT=ALL ERROR WARNING INFO -LOG.RDK.CPUPROCANALYZER=ERROR WARNING INFO -LOG.RDK.XCV=ALL ERROR WARNING INFO -LOG.RDK.AKER = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.RTMESSAGE = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.RBUS = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.RBUSCORE = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.DYNAMICLOG = ALL ERROR WARNING INFO -LOG.RDK.XWCONFIG = ALL FATAL ERROR WARNING INFO -LOG.RDK.LIBSYSCALLWRAPPER = ALL FATAL WARNING NOTICE INFO DEBUG ERROR -LOG.RDK.PRVNMGR = ALL FATAL ERROR WARNING INFO -LOG.RDK.SPDTST = ALL FATAL ERROR WARNING NOTICE INFO DEBUG TRACE -LOG.RDK.BREAKPAD=ALL FATAL ERROR WARNING INFO DEBUG -LOG.RDK.BLE=ALL FATAL ERROR WARNING INFO DEBUG -LOG.RDK.HWST = ERROR -LOG.RDK.IAVENCODER=ALL ERROR WARNING INFO -LOG.RDK.WEBCONFIG=ALL ERROR WARNING INFO -LOG.RDK.MQTTCM=ALL ERROR WARNING INFO -LOG.RDK.WATCHDOG=ALL ERROR WARNING INFO -LOG.RDK.SMARTRC=ALL FATAL ERROR WARNING INFO -LOG.RDK.XSTREAM=ALL FATAL ERROR WARNING INFO -LOG.RDK.XAUDIO=ALL FATAL ERROR WARNING INFO -LOG.RDK.XSENSOR=ALL FATAL ERROR WARNING INFO -LOG.RDK.BATTMGR = ALL FATAL ERROR WARNING INFO -LOG.RDK.BUTTONMGR = ALL FATAL ERROR WARNING INFO -LOG.RDK.ADVSEC = ALL FATAL WARNING NOTICE INFO DEBUG ERROR -LOG.RDK.XDNS = ALL FATAL ERROR WARNING NOTICE INFO DEBUG TRACE -LOG.RDK.XWBANDMON = ALL FATAL ERROR WARNING INFO -LOG.RDK.XWWATCHDOG = ALL FATAL ERROR WARNING INFO -LOG.RDK.SYSTIMEMGR = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCP = ALL FATAL ERROR WARNING NOTICE INFO DEBUG -LOG.RDK.T2 = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MEDIAPIPE = ALL ERROR WARNING INFO -LOG.RDK.FWUPG = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.COMMONUTILITIES = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.REMOTEDEBUGGER = ALL FATAL WARNING NOTICE INFO DEBUG ERROR -LOG.RDK.RDKCPROVIDER = ALL ERROR WARNING INFO -LOG.RDK.WANCNCTVTYCHK = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.NLMON = ALL ERROR WARNING INFO FATAL -LOG.RDK.RFCMGR = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RFCAPI = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FLASHAPP = ALL FATAL ERROR WARNING INFO -LOG.RDK.DCM = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RDKSSACERTCHECK = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RDMAGENT = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LXY = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.IPCONTROL = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RDKSSADAEMON = ERROR WARNING -LOG.RDK.LNF = ALL FATAL ERROR WARNING NOTICE INFO DEBUG TRACE -LOG.RDK.CERTSELECTOR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.NFRTOOL = ALL FATAL ERROR WARNING INFO DEBUG -LOG.RDK.SUBS.REND = FATAL ERROR WARNING INFO -LOG.RDK.SUBS.GFX = FATAL ERROR WARNING INFO -LOG.RDK.SUBS.CORE = FATAL ERROR WARNING INFO -LOG.RDK.MFRHAL = ALL FATAL ERROR WARNING INFO +LOG.RDK.DEFAULT = INFO diff --git a/debug.ini.sample b/debug.ini.sample new file mode 100644 index 0000000..38a0e41 --- /dev/null +++ b/debug.ini.sample @@ -0,0 +1,33 @@ +########################################################################## +# debug.ini.sample - Example configuration for RDK Logger +# +# Each line sets the logging level for a module. +# Format: +# LOG.RDK.= +# +# Log levels (from most to least verbose): +# TRACE - Enables TRACE, DEBUG, INFO, NOTICE, WARN, ERROR, FATAL +# DEBUG - Enables DEBUG, INFO, NOTICE, WARN, ERROR, FATAL +# INFO - Enables INFO, NOTICE, WARN, ERROR, FATAL +# NOTICE - Enables NOTICE, WARN, ERROR, FATAL +# WARN - Enables WARN, ERROR, FATAL +# ERROR - Enables ERROR, FATAL +# FATAL - Enables FATAL only +# +# LOG.RDK.DEFAULT sets the default log level for all modules not explicitly listed. +########################################################################## + +LOG.RDK.DEFAULT=WARNING +# All modules not listed (no override) will log WARN, ERROR, and FATAL messages + +#LOG.RDK.TEST=DEBUG +# Enables DEBUG and all higher-severity logs (INFO, NOTICE, WARN, ERROR, FATAL) for LOG.RDK.TEST + +#LOG.RDK.SAMPLE=INFO +# Enables INFO and all higher-severity logs (NOTICE, WARN, ERROR, FATAL) for LOG.RDK.SAMPLE + +LOG.RDK.FOO=INFO +# LOG.RDK.FOO will log INFO, NOTICE, WARN, ERROR, and FATAL messages + +LOG.RDK.BAR = NONE +#ALL logs will be disabled for this module diff --git a/include/Makefile.am b/include/Makefile.am index 420a9ba..5407b1e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -19,4 +19,4 @@ SUBDIRS = librdkloggers_la_includedir = $(includedir) -librdkloggers_la_include_HEADERS = rdk_debug.h rdk_error.h rdk_logger_types.h rdk_utils.h rdk_logger_milestone.h +librdkloggers_la_include_HEADERS = rdk_debug.h rdk_error.h rdk_logger_types.h rdk_logger_milestone.h diff --git a/include/rdk_debug.h b/include/rdk_debug.h index ded4017..5234991 100644 --- a/include/rdk_debug.h +++ b/include/rdk_debug.h @@ -116,13 +116,13 @@ * @par Logging Levels supported by RDK Logger. * Code | Description * -----|------------ - * RDK_LOG_FATAL | Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss), reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss. - * RDK_LOG_ERROR | Any error which is fatal to the operation but not the service (cant open a file, missing data, etc) - * RDK_LOG_WARN | Anything that can potentially cause application oddities, but for which the application automatically recoverring. - * RDK_LOG_NOTICE | Anything that largely superfluous for application-level logging. - * RDK_LOG_INFO | Generally useful information to log (service start/stop, configuration assumptions, etc). - * RDK_LOG_DEBUG | Information that is diagnostically helpful to people more than just developers. - * RDK_LOG_TRACE | Only when it would be "tracing" the code and trying to find one part of a function specifically. + * RDK_LOG_FATAL | Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss), reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss. + * RDK_LOG_ERROR | Any error which is fatal to the operation but not the service (cant open a file, missing data, etc) + * RDK_LOG_WARN | Anything that can potentially cause application oddities, but for which the application automatically recoverring. + * RDK_LOG_NOTICE | Anything that largely superfluous for application-level logging. + * RDK_LOG_INFO | Generally useful information to log (service start/stop, configuration assumptions, etc). + * RDK_LOG_DEBUG | Information that is diagnostically helpful to people more than just developers. + * RDK_LOG_TRACE | Only when it would be "tracing" the code and trying to find one part of a function specifically. * * @par How log files are upload to server * @image html rdk_logupload.jpg @@ -159,13 +159,25 @@ extern "C" /** * Macros for ease of applications using RDK_LOGGER apis */ + +/** + * Define the default location of configuration file location + */ +#define DEBUG_INI_NAME "/etc/debug.ini" + /** * Support for overriding debug.ini file location */ -#define DEBUG_INI_OVERRIDE_PATH "/opt/debug.ini" -#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ - ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ - : rdk_logger_init(DEBUG_INI_NAME); +#ifndef DEBUG_INI_OVERRIDE_PATH +#define DEBUG_INI_OVERRIDE_PATH "/nvram/debug.ini" +#endif + +/** + * Support for Init function + */ +#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ + ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ + : rdk_logger_init(DEBUG_INI_NAME); /** * Use RDK_LOG debug message as. * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) @@ -176,30 +188,18 @@ extern "C" #define RDK_LOG rdk_logger_msg_printf #define RDK_LOG1 rdk_logger_msg_vsprintf - /** - * @enum rdk_LogLevel - * @brief These values represent the logging 'levels' or 'types', they are each - * independent. + * Define the max length for the log file capture */ -typedef enum -{ - ENUM_RDK_LOG_BEGIN = 0, /**< Used as array index. */ +#define RDK_LOGGER_EXT_FILENAME_SIZE 32 - RDK_LOG_FATAL = ENUM_RDK_LOG_BEGIN, - RDK_LOG_ERROR, - RDK_LOG_WARN, - RDK_LOG_NOTICE, - RDK_LOG_INFO, - RDK_LOG_DEBUG, - - RDK_LOG_TRACE, - - ENUM_RDK_LOG_COUNT -} rdk_LogLevel; +/** + * Define the max length for the log capture path + */ +#define RDK_LOGGER_EXT_LOGDIR_SIZE 32 /** - * To allow compatibility of mutiple rdke components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 and function rdk_dbg_enabled + * To allow compatibility of mutiple legacy RDK components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 */ #define RDK_LOG_TRACE1 RDK_LOG_TRACE #define RDK_LOG_TRACE2 RDK_LOG_TRACE @@ -211,47 +211,98 @@ typedef enum #define RDK_LOG_TRACE8 RDK_LOG_TRACE #define RDK_LOG_TRACE9 RDK_LOG_TRACE +/** + * An access function macro to check logging is enabled or not + */ #define rdk_dbg_enabled rdk_logger_is_logLevel_enabled /** - * String names that correspond to the various logging types. - * Note: This array *must* match the RDK_LOG_* enum. + * @enum rdk_LogLevel + * @brief These values represent the logging 'levels' or 'types', they are each + * independent. */ -#ifdef RDK_DEBUG_DEFINE_STRINGS -const char *rdk_logLevelStrings[ENUM_RDK_LOG_COUNT] = +typedef enum { - "FATAL", - "ERROR", - "WARNING", - "NOTICE", - "INFO", - "DEBUG", + RDK_LOG_FATAL = 0, + RDK_LOG_ERROR, + RDK_LOG_WARN, + RDK_LOG_NOTICE, + RDK_LOG_INFO, + RDK_LOG_DEBUG, + RDK_LOG_TRACE, + RDK_LOG_NONE +} rdk_LogLevel; - "TRACE", -}; -#endif /* RDK_DEBUG_DEFINE_STRINGS */ +typedef struct rdk_logger_ext_config_t + { + char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; + char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; + long maxSize; + long maxCount; + }rdk_logger_ext_config_t; /** - * @ingroup RDKLOGGER_DEBUG_API - * @{ + * @brief Initialize the RDK Logger. + * @param debugConfigFile Path to the debug.ini configuration file. + * @return RDK_SUCCESS on success, error code otherwise. */ - rdk_Error rdk_logger_init(const char* debugConfigFile); -rdk_Error rdk_logger_deinit(); +/** + * @brief Extended initialization for RDK Logger. + * @param config Pointer to rdk_logger_ext_config_t structure. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config); -void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +/** + * @brief Deinitialize the RDK Logger. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_deinit(void); -void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module,const char *format, va_list args); +/** + * @brief Log a message with printf-style formatting. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + */ +void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...); +/** + * @brief Log a message using a va_list. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + * @param args va_list of arguments. + */ +void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args); + +/** + * @brief Check if a log level is enabled for a module. + * @param module Module name. + * @param level Log level. + * @return TRUE if enabled, FALSE otherwise. + */ rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); +/** + * @brief Enable or disable a log level for a module. + * @param module Module name. + * @param logLevel Log level. + * @param enableLogLvl TRUE to enable, FALSE to disable. + * @return TRUE if successful, FALSE otherwise. + */ rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); +/** + * @brief Log a message for onboard logging. + * @param module Module name. + * @param msg Message to log. + */ void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribute__ ((format (printf, 2, 3))); -/** @} */ //end of Doxygen tag RDKLOGGER_DEBUG_API - +/** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API #ifdef __cplusplus } diff --git a/log4crc b/log4crc index 0bf7322..67f35fe 100644 --- a/log4crc +++ b/log4crc @@ -1,184 +1,39 @@ - - - - - - 0 - - 0 - 0 - - - - - - - - - - - - - - - - - - + 0 - + - - - - - - - - - - - + 0 - + 0 - + - - - - - - - - - + - - - - - - - - - - - - - - + - - + - + - - - - - + - + diff --git a/rdkb_debug.ini b/rdkb_debug.ini deleted file mode 100644 index 7c4a908..0000000 --- a/rdkb_debug.ini +++ /dev/null @@ -1,98 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#### Logging #### - -EnableMPELog = TRUE - -SEPARATE.LOGFILE.SUPPORT=FALSE -LOG.RDK.DEFAULT = WARNING -LOG.RDK.RTMESSAGE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TR69 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PAM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PSM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MOCA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MTA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TDM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WIFI = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMRXM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMBRG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMRBP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMMON = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SSD = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FU = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.IMAGEHEALTHCHECKER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Misc = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SNMP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBPA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Harvester = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.HOTSPOT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCPSNOOP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.NOTIFY = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WECB = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WECBMASTER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XSMART = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TOUCHSTONE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FSC = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PWRMGR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MESH = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.T2 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MeshService = FATAL ERROR WARNING NOTICE INFO DEBUG TRACE -LOG.RDK.ETHAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCPMGR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GWPROV = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Seshat = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PARODUS = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.AKER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GWPROVETHWAN = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GWPROVGPONWAN = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LIBSYSCALLWRAPPER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SPDTST = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BLE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BTRCORE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BTRMGR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WANAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TELCOVOIPAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBCONFIG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MQTTCM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.ADVSEC = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XDNS = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DSLAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.VLANAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XTMAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CERTSELECTOR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CPUPROCANALYZER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.HWST = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.OVSAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WANMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WANCNCTVTYCHK = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MAPTLOG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.VLANMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GPONMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FWUPGRADEMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BATTERYMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CELLULARMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.INTERDEVICEMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GATEWAYMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LANMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PLATFORMMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.EASYMESHCTL = FATAL ERROR WARNING INFO -LOG.RDK.WEBCONFIGRFC = FATAL ERROR WARNING NOTICE INFO diff --git a/rdkb_debug_arm.ini b/rdkb_debug_arm.ini deleted file mode 100644 index 2b5996c..0000000 --- a/rdkb_debug_arm.ini +++ /dev/null @@ -1,58 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#### Logging #### - -EnableMPELog = TRUE - -SEPARATE.LOGFILE.SUPPORT=FALSE -LOG.RDK.DEFAULT = WARNING -LOG.RDK.TR69 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PAM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PSM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MOCA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MTA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TDM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SSD = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FU = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Misc = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SNMP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBPA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.HOTSPOT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCPSNOOP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.NOTIFY = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WECB = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WECBMASTER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.ETHAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCPMGR = ALL FATAL ERROR WARNING NOTICE INFO DEBUG -LOG.RDK.GWPROV = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PARODUS = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.AKER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RTMESSAGE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GWPROVETHWAN = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LIBSYSCALLWRAPPER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SPDTST = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.T2 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBCONFIG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.ADVSEC = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XDNS = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CPUPROCANALYZER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.IMAGEHEALTHCHECKER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBCONFIGRFC = ALL FATAL ERROR WARNING NOTICE INFO DEBUG TRACE diff --git a/rdkb_debug_atom.ini b/rdkb_debug_atom.ini deleted file mode 100644 index 66f72a7..0000000 --- a/rdkb_debug_atom.ini +++ /dev/null @@ -1,43 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#### Logging #### - -EnableMPELog = TRUE - -SEPARATE.LOGFILE.SUPPORT=FALSE -LOG.RDK.DEFAULT = WARNING -LOG.RDK.CR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WIFI = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMRXM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMBRG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMRBP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMMON = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Harvester = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XSMART = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TOUCHSTONE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MESH = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MeshService = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBPA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Seshat = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SPDTST = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BLE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.T2 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBCONFIG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RTMESSAGE = FATAL ERROR WARNING NOTICE INFO - diff --git a/rdkb_log4crc b/rdkb_log4crc deleted file mode 100644 index cd7c6f6..0000000 --- a/rdkb_log4crc +++ /dev/null @@ -1,517 +0,0 @@ - - - - - - - - - - 0 - - 0 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rdkb_log4crc_arm b/rdkb_log4crc_arm deleted file mode 100644 index 61ae7aa..0000000 --- a/rdkb_log4crc_arm +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - - - - - 0 - - 0 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rdkb_log4crc_atom b/rdkb_log4crc_atom deleted file mode 100644 index 1b62d0a..0000000 --- a/rdkb_log4crc_atom +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - - - - 0 - - 0 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rdkc_log4crc b/rdkc_log4crc deleted file mode 100644 index ccdba99..0000000 --- a/rdkc_log4crc +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - 0 - - 0 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/include/rdk_debug_priv.h b/src/include/rdk_debug_priv.h index aed40b0..b2b71c4 100644 --- a/src/include/rdk_debug_priv.h +++ b/src/include/rdk_debug_priv.h @@ -29,50 +29,17 @@ extern "C" { #endif -/** Maximum limit on the number of Modules logged*/ +void rdk_dbg_priv_init(void); +void rdk_dbg_priv_config(void); +void rdk_dbg_priv_deinit(void); +void rdk_dbg_priv_ext_init(const char* logdir, const char* log_file_name, long maxCount, long maxSize); +void rdk_dbg_priv_shutdown(); -#define RDK_MAX_MOD_COUNT 512 +void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args); +void rdk_dbg_priv_reconfig(const char *pModuleName, const char *pLogLevel); -/** This variable is described in rdk_dbg_priv_log.c - to be used by - * rdk_debug_priv_.* files only. - */ -extern uint32_t rdk_g_logControlTbl[]; -extern rdk_logger_Bool dbg_logViaUDP; - -/** - * The rdk_logger_envGet() function will get the value of the specified - * environment variable. - * - * @param name is a pointer to the name of the target environment variable. - * - * @return a pointer to the associated string value of the target environment - * variable or NULL if the variable can't be found. - */ -const char* rdk_logger_envGet(const char *name); - -/** - * The rdk_logger_env_add_conf_file() function sets up the environment variable - * storage by parsing configuration file. - * - * @param path Path of the file. - * @return Returns relevant RDK_OSAL error code on failure, otherwise RDK_SUCCESS - * is returned. - */ -rdk_Error rdk_logger_env_add_conf_file(const char * path); -rdk_Error rdk_logger_env_rem_conf_details(void); - -void rdk_dbg_priv_LogControlInit(void); -void rdk_dbg_priv_Init(void); -void rdk_dbg_priv_DeInit(void); -void rdk_dbg_priv_Shutdown(); -const char * rdk_dbg_priv_LogControlOpSysIntf(char *logName, char *cfgStr); -const char * rdk_dbg_priv_LogQueryOpSysIntf(char *modName, char *cfgStr, int cfgStrMaxLen); -void rdk_debug_priv_log_msg( rdk_LogLevel level, - int module, const char *module_name, const char* format, va_list args); -void RDK_LOG_ControlCB(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status); -void rdk_dbgDumpLog(const char* path); -void rdk_dbgInit(); -void rdk_dbgDeinit(); +void rdk_dbg_init(); +void rdk_dbg_deinit(); #ifdef __cplusplus } diff --git a/src/include/rdk_dynamic_logger.h b/src/include/rdk_dynamic_logger.h index 9c8f13f..e087e0a 100644 --- a/src/include/rdk_dynamic_logger.h +++ b/src/include/rdk_dynamic_logger.h @@ -22,11 +22,7 @@ #include -void rdk_dyn_log_processPendingRequest(void); - void rdk_dyn_log_init(void); - -void rdk_dyn_log_deInit(void); - -char* rdk_loglevelToString(unsigned char log_level, rdk_LogLevel isLogEnabled); +void rdk_dyn_log_deinit(void); +void rdk_dyn_log_process_pending_request(void); #endif /* _RDK_DBG_PRIV_DYNLOG_H */ diff --git a/include/rdk_utils.h b/src/include/rdk_utils.h similarity index 88% rename from include/rdk_utils.h rename to src/include/rdk_utils.h index 9d228d4..ee19f25 100644 --- a/include/rdk_utils.h +++ b/src/include/rdk_utils.h @@ -36,7 +36,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -55,8 +54,11 @@ const char* rdk_logger_envGetValueFromNum(int number); const char* rdk_logger_envGetModFromNum(int Num); -rdk_Error rdk_logger_env_add_conf_file(const char * path); +rdk_Error rdk_logger_parse_config(const char * path); +rdk_Error rdk_logger_release_config(void); + +char* rdk_loglevelToString(rdk_LogLevel level, rdk_logger_Bool isLogEnabled); /** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API #ifdef __cplusplus diff --git a/src/rdk_debug.c b/src/rdk_debug.c index 6f8b01f..a78d0b0 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -37,78 +37,23 @@ #include #include -extern int global_count; - -/** - * @brief Touch the file which can be used to check whether to log or not. - * - * @param[in] pszFile Character string representing name of the file to be created. - * @return None. - */ -static void TouchFile(const char * pszFile) -{ - if(NULL != pszFile) - { - FILE * fp = fopen(pszFile, "w"); - if(NULL != fp) - { - fclose(fp); - } - } -} - -/** - * @brief Dump the debug log. It will Dump all the current settings so that an analysis of a log - * file will include what logging information to expect. - * - * @param[in] path Character string representing path of the temp file to be created. - * @return None. - */ -void rdk_dbgDumpLog(const char* path) -{ - int mod, i; - char config[128]; - const char *modptr = NULL; - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", "\n"); - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", - "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"); - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", "Stack level logging levels: \n"); - - /** - * Now just dump all the current settings so that an analysis of a log - * file will include what logging information to expect - */ - for (mod = 1; mod <= global_count; mod++) - { - modptr = rdk_logger_envGetModFromNum(mod); - - memset(config, 0, sizeof(config)); - (void) rdk_dbg_priv_LogQueryOpSysIntf((char*) modptr, config, 127); - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", - "Initial Logging Level for %-10s: %s\n", modptr, config); - } - - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", - "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n"); - TouchFile(path); -} - /** * @brief Initialize the underlying MPEOS debug support. This API must be called only once per boot cycle. * @return None. */ static rdk_logger_Bool inited = FALSE; -void rdk_dbgInit() +void rdk_dbg_init() { if (!inited) { - rdk_dbg_priv_Init(); + rdk_dbg_priv_init(); inited = TRUE; + rdk_dbg_priv_config(); } } -void rdk_dbgDeinit() +void rdk_dbg_deinit() { if (inited) { @@ -124,41 +69,40 @@ void rdk_dbgDeinit() * @param[in] module The name of the module for which this message belongs to, it is mentioned in debug.ini. * @param[in] format Printf style string containing the log message. */ -void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, - const char *format, ...) +void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...) { -#if !defined(RDK_LOG_DISABLE) int num; va_list args; va_start(args, format); - /** Get the registered value of module */ - num = rdk_logger_envGetNum(module); - if(num < 0) - { - va_end(args); - return; - } - rdk_debug_priv_log_msg( level, num, module, - format, args); + rdk_dbg_priv_log_msg(level, module, format, args); va_end(args); -#endif /* RDK_LOG_DISABLE */ } -void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, - const char *format, va_list args) +void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args) { -#if !defined(RDK_LOG_DISABLE) - int num; + rdk_dbg_priv_log_msg(level, module, format, args); +} - /** Get the registered value of module */ - num = rdk_logger_envGetNum(module); - if(num < 0) - { - return; - } - rdk_debug_priv_log_msg( level, num, module, - format, args); -#endif /* RDK_LOG_DISABLE */ +/** + * @brief Function to sets a specific log level of a module. + * + * @param[in] module The module name or category for for which the log level shall be checked + * @param[in] level The debug logging level. + * + * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. + */ +rdk_logger_Bool rdk_logger_enable_logLevel(const char *pModuleName, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl) +{ + if (!pModuleName) + return FALSE; + + const char* logLevelName = rdk_loglevelToString(logLevel, enableLogLvl); + + if (!logLevelName) + return FALSE; + + rdk_dbg_priv_reconfig (pModuleName, logLevelName); + return TRUE; } diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index 3456cb0..0e6ba8a 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -54,6 +54,9 @@ #include "rdk_dynamic_logger.h" #include "log4c.h" #include +#include +#include +#include #ifdef SYSTEMD_JOURNAL #include @@ -64,32 +67,36 @@ #include "syslog_helper_ifc.h" #endif -/// Debugging messages are enabled. Default is enabled (1) and 0 for off. -static int g_debugEnabled = 1; - +log4c_category_t* gRootCat = NULL; +int gRootPriority = 0; extern int global_count; +static int rdk_logLevel_to_log4c_priority(int level) { + switch (level) { + case 0: return LOG4C_PRIORITY_FATAL; // 000 + case 1: return LOG4C_PRIORITY_ERROR; // 300 + case 2: return LOG4C_PRIORITY_WARN; // 400 + case 3: return LOG4C_PRIORITY_NOTICE; // 500 + case 4: return LOG4C_PRIORITY_INFO; // 600 + case 5: return LOG4C_PRIORITY_DEBUG; // 700 + case 6: return LOG4C_PRIORITY_TRACE; // 800 + default: return LOG4C_PRIORITY_UNKNOWN; + } + } + +#define LOG4C_PRIORITY_NONE -1 + /** * Returns 1 if logging has been requested for the corresponding module (mod) * and level (lvl) combination. To be used in rdk_dbg_priv_* files ONLY. */ -#define WANT_LOG(mod, lvl) ( ( ((mod) >= 0) && ((mod) < RDK_MAX_MOD_COUNT) ) ? (rdk_g_logControlTbl[(mod)] & (1 << (lvl))) : 0 ) - +#define IS_LOGGING_ENABLED_FOR_LEVEL(module_name, level) \ + (log4c_category_get(module_name) && \ + (rdk_logLevel_to_log4c_priority(level) <= log4c_category_get_priority(log4c_category_get(module_name)))) /** Skip whitespace in a c-style string. */ #define SKIPWHITE(cptr) while ((*cptr != '\0') && isspace(*cptr)) cptr++ -/** Bit mask for trace TRACE logging level. */ -#define LOG_TRACE ( (1 << RDK_LOG_TRACE) ) - -/** Turns on FATAL, ERROR, WARN NOTICE & INFO. */ -#define LOG_ALL ( (1 << RDK_LOG_FATAL) | (1 << RDK_LOG_ERROR) | \ - (1 << RDK_LOG_WARN) | (1 << RDK_LOG_INFO) | \ - (1 << RDK_LOG_NOTICE)) - -/** All logging 'off'. */ -#define LOG_NONE 0 - #define HOSTADDR_STR_MAX 255 @@ -113,28 +120,6 @@ static int stream_env_close(log4c_appender_t * appender); static rdk_logger_Bool g_initialized = FALSE; - -/** Global variable used to control logging. */ -uint32_t rdk_g_logControlTbl[RDK_MAX_MOD_COUNT]; - -/** UDP logging variables. */ -rdk_logger_Bool dbg_logViaUDP = FALSE; -int dbg_udpSocket; -struct sockaddr_in dbg_logHostAddr; - -log4c_category_t* stackCat = NULL; - -enum -{ - /** Used as an array index. */ - ERR_INVALID_MOD_NAME = 0, ERR_INVALID_LOG_NAME -}; - -enum -{ - RC_ERROR, RC_OK -}; - static const char *errorMsgs[] = { "Error: Invalid module name.", "Warning: Ignoring invalid log name(s)." }; @@ -142,9 +127,6 @@ static const char *errorMsgs[] = /** * Initialize Debug API. */ -static log4c_category_t* defaultCategory = NULL; -static log4c_category_t* glibCategory = NULL; - static const log4c_layout_type_t log4c_layout_type_dated_nocr = { "dated_nocr", dated_format_nocr, }; @@ -171,30 +153,62 @@ static const log4c_appender_type_t log4c_appender_type_stream_env_append_plus_st { "stream_env_append_plus_stdout", stream_env_append_open, stream_env_plus_stdout_append, stream_env_close, }; -void rdk_dbg_priv_Init() +void rdk_dbg_priv_init() { const char* envVar; - if (initLogger("RI")) + if (initLogger("LOG.RDK")) { fprintf(stderr, "%s -- initLogger failure?!\n", __FUNCTION__); } - stackCat = log4c_category_get("RI.Stack"); + gRootCat = log4c_category_get("LOG.RDK"); +} + +void rdk_dbg_priv_ext_init(const char* logdir, const char* log_file_name, long maxCount, long maxSize) +{ + char fullpath[512]; + snprintf(fullpath, sizeof(fullpath), "%s/%s", logdir, log_file_name); - rdk_dbg_priv_LogControlInit(); + const char* cat_name = "LOG.RDK"; + log4c_category_t* cat = log4c_category_get(cat_name); + if (!cat) { + cat = log4c_category_new(cat_name); + } - /* Try to get logging option. */ - envVar = rdk_logger_envGet("EnableMPELog"); - if (NULL != envVar) - { - g_debugEnabled = (strcasecmp(envVar, "TRUE") == 0); + log4c_appender_t* app = log4c_appender_get(fullpath); + if (!app) { + app = log4c_appender_new(fullpath); } + log4c_appender_set_type(app, log4c_appender_type_get("rollingfile")); + + rollingfile_udata_t *rudata = rollingfile_make_udata(); + rollingfile_udata_set_logdir(rudata, logdir); + rollingfile_udata_set_files_prefix(rudata, log_file_name); + + log4c_rollingpolicy_t *policy = log4c_rollingpolicy_get(cat_name); + if (!policy) { + policy = log4c_rollingpolicy_new(cat_name); + } + log4c_rollingpolicy_set_type(policy, log4c_rollingpolicy_type_get("sizewin")); + + rollingpolicy_sizewin_udata_t *sizewin_udata = sizewin_make_udata(); + sizewin_udata_set_file_maxsize(sizewin_udata, maxSize); + sizewin_udata_set_max_num_files(sizewin_udata, maxCount); + log4c_rollingpolicy_set_udata(policy, sizewin_udata); + + rollingfile_udata_set_policy(rudata, policy); + log4c_appender_set_udata(app, rudata); + + log4c_layout_t* layout = log4c_layout_get("comcast_dated"); + log4c_appender_set_layout(app, layout); + + log4c_category_set_appender(cat, app); } -void rdk_dbg_priv_DeInit() +void rdk_dbg_priv_deinit() { - stackCat = NULL; + gRootCat = NULL; } /** @@ -214,6 +228,21 @@ static void forceUpperCase(char *token) } } +/** + * String names that correspond to the various logging types. + * Note: This array *must* match the RDK_LOG_* enum. + */ +const char *rdk_logLevelStrings[RDK_LOG_NONE] = +{ + "FATAL", + "ERROR", + "WARNING", + "NOTICE", + "INFO", + "DEBUG", + "TRACE", +}; + /** * Convert a log level name to the correspodning log level enum value. * @@ -223,7 +252,7 @@ static void forceUpperCase(char *token) static int logNameToEnum(const char *name) { int i = 0; - while (i < ENUM_RDK_LOG_COUNT) + while (i < RDK_LOG_NONE) { if (strcmp(name, rdk_logLevelStrings[i]) == 0) { @@ -256,101 +285,6 @@ static void extractToken(const char **srcStr, char *tokBuf) *srcStr = src; } -/** - * Parse a whitespace delimited list of log types and log type meta names. - * - * @param cfgStr String containing one more log types. (Right hand - * side of INI file entry.) - * - * @param defConfig Default configuration to base the return value on. - * - * @return Returns a bit mask that can be used as an entry in - * #rdk_g_logControlTbl. - */ -static int parseLogConfig(const char *cfgStr, uint32_t *configEntry, - const char **msg) -{ - uint32_t config = *configEntry; - char logTypeName[128] = - { 0 }; - int rc = RC_OK; - - *msg = ""; - - SKIPWHITE(cfgStr) - ; - if (*cfgStr == '\0') - { - *msg = "Warning: Empty log level confguration."; - return RC_ERROR; - } - - while (*cfgStr != '\0') - { - /* Extract and normalise log type name token. */ - - memset(logTypeName, 0, sizeof(logTypeName)); - extractToken(&cfgStr, logTypeName); - forceUpperCase(logTypeName); - - /* Handle special meta names. */ - - if (strcmp(logTypeName, "ALL") == 0) - { - config |= LOG_ALL; - } - else if (strcmp(logTypeName, "NONE") == 0) - { - config = LOG_NONE; - } - else if (strcmp(logTypeName, "TRACE") == 0) - { - config |= LOG_TRACE; - } - else if (strcmp(logTypeName, "!TRACE") == 0) - { - config &= ~LOG_TRACE; - } - else - { - /* Determine the corresponding bit for the log name. */ - int invert = 0; - const char *name = logTypeName; - int logLevel = -1; - - if (logTypeName[0] == '!') - { - invert = 1; - name = &logTypeName[1]; - } - - logLevel = logNameToEnum(name); - if (logLevel != -1) - { - if (invert) - { - config &= ~(1 << logLevel); - } - else - { - config |= (1 << logLevel); - } - } - else - { - *msg = errorMsgs[ERR_INVALID_LOG_NAME]; - rc = RC_ERROR; - } - } - - SKIPWHITE(cfgStr) - ; - } - - *configEntry = config; - return rc; -} - static void printTime(const struct tm *pTm, char *pBuff) { sprintf(pBuff,"%02d%02d%02d-%02d:%02d:%02d",pTm->tm_year + 1900 - 2000, pTm->tm_mon + 1, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec); @@ -361,138 +295,91 @@ static void printTime(const struct tm *pTm, char *pBuff) * EXPORTED FUNCTIONS * ****************************************************************************/ - -/** - * Initialize the debug log control table. This should be called from - * the initialization routine of the debug manager. - */ -void rdk_dbg_priv_LogControlInit(void) +void rdk_dbg_priv_config(void) { - char envVarName[128] = - { 0 }; - const char *envVarValue = NULL; - uint32_t defaultConfig = 0; - int mod = 0; - const char *msg = ""; - - /** Pre-condition the control table to disable all logging. This - * means that if no logging control statements are present in the - * debug.ini file all logging will be suppressed. */ - memset(rdk_g_logControlTbl, 0, sizeof(rdk_g_logControlTbl)); - - /** Intialize to the default configuration for all modules. */ - strncpy(envVarName,"LOG.RDK.DEFAULT",sizeof(envVarName)); - envVarValue = rdk_logger_envGet(envVarName); - if ((envVarValue != NULL) && (envVarValue[0] != 0)) + const char *defaultValue = rdk_logger_envGet("LOG.RDK.DEFAULT"); + if (defaultValue && defaultValue[0] != 0) { - (void) parseLogConfig(envVarValue, &defaultConfig, &msg); - for (mod = 1; mod <= global_count; mod++) + char levelName[32]; + strncpy(levelName, defaultValue, sizeof(levelName)-1); + levelName[sizeof(levelName)-1] = '\0'; + forceUpperCase(levelName); + + if (!gRootCat) + gRootCat = log4c_category_get("LOG.RDK"); + + if (!gRootCat) { - rdk_g_logControlTbl[mod] = defaultConfig; + printf("LOG.RDK.DEFAULT is not defined..\n"); + return; } - } - /** Configure each module from the ini file. Note: It is not an - * error to have no entry in the ini file for a module - we simply - * leave it at the default logging. */ - for (mod = 1; mod <= global_count; mod++) - { - /** Get the logging level */ - envVarValue = rdk_logger_envGetValueFromNum(mod); - if ((envVarValue != NULL) && (envVarValue[0] != '\0')) + if (strcasecmp(levelName, "NONE") == 0) { - (void) parseLogConfig(envVarValue, &rdk_g_logControlTbl[mod], - &msg); + log4c_category_set_priority(gRootCat, LOG4C_PRIORITY_NONE); } - } -} - -/** - * @brief Function to check if a specific log level of a module is enabled. - * - * @param[in] module The module name or category for for which the log level shall be checked (as mentioned in debug.ini). - * @param[in] level The debug logging level. - * - * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. - */ -rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level) -{ - int number = rdk_logger_envGetNum(module); - if (WANT_LOG(number, level)) - { - return TRUE; - } - else - { - return FALSE; - } -} - -/** - * Modify the debug log control table. - */ -void rdk_dbg_priv_SetLogLevelString(const char* pszModuleName, const char* pszLogLevels) -{ - const char *envVarName; - uint32_t defaultConfig = 0; - int mod = 0; - const char *msg = ""; - - if ((pszModuleName != NULL) && (pszLogLevels != NULL)) - { - /* Intialize to the default configuration for all modules. */ - if(0 == strcmp(pszModuleName, "LOG.RDK.DEFAULT")) + else { - (void) parseLogConfig(pszLogLevels, &defaultConfig, &msg); - for (mod = 1; mod <= global_count; mod++) + int lvl = logNameToEnum(levelName); + if (lvl >= 0 && lvl < RDK_LOG_NONE) { - rdk_g_logControlTbl[mod] = defaultConfig; + log4c_category_set_priority(gRootCat, rdk_logLevel_to_log4c_priority(lvl)); } - printf("rdk_dbg_priv_SetLogLevelString: Set Logging Level for '%s' to '%s'\n", pszModuleName, pszLogLevels); - return; } + gRootPriority = log4c_category_get_priority(gRootCat); + } + else + { + printf("LOG.RDK.DEFAULT is not defined..\n"); + return; + } - /* Configure each module from the ini file. Note: It is not an - * error to have no entry in the ini file for a module - we simply - * leave it at the default logging. */ - for (mod = 1; mod <= global_count; mod++) + for (int mod = 1; mod <= global_count; mod++) + { + const char* modName = rdk_logger_envGetModFromNum(mod); + const char* modValue = rdk_logger_envGetValueFromNum(mod); + if (modName && modValue && modValue[0] != '\0') { - envVarName = rdk_logger_envGetModFromNum(mod); - if(0 == strcmp(pszModuleName, envVarName)) + char levelName[32]; + strncpy(levelName, modValue, sizeof(levelName)-1); + levelName[sizeof(levelName)-1] = '\0'; + forceUpperCase(levelName); + + log4c_category_t* cat = log4c_category_get(modName); + if (cat) { - if ((pszLogLevels != NULL) && (pszLogLevels[0] != '\0')) + if (strcasecmp(levelName, "NONE") == 0) + { + log4c_category_set_priority(cat, LOG4C_PRIORITY_NONE); + } + else { - (void) parseLogConfig(pszLogLevels, &rdk_g_logControlTbl[mod], &msg); - //printf("rdk_dbg_priv_SetLogLevelString: Set Logging Level for '%s' to '%s'\n", pszModuleName, pszLogLevels); - return; + int lvl = logNameToEnum(levelName); + if (lvl >= 0 && lvl < RDK_LOG_NONE) + { + log4c_category_set_priority(cat, rdk_logLevel_to_log4c_priority(lvl)); + } + else + { + log4c_category_set_priority(cat, LOG4C_PRIORITY_NONE); + } } } } } - printf("rdk_dbg_priv_SetLogLevelString: Failed to set Logging Level for '%s' to '%s'\n", pszModuleName, pszLogLevels); } /** - * @brief Function to sets a specific log level of a module. + * @brief Function to check if a specific log level of a module is enabled. * * @param[in] module The module name or category for for which the log level shall be checked (as mentioned in debug.ini). * @param[in] level The debug logging level. * * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. */ -rdk_logger_Bool rdk_logger_enable_logLevel(const char *moduleName, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl) +rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level) { - const char* logLevelName = rdk_loglevelToString(logLevel, enableLogLvl); - - if ((NULL == moduleName) || (NULL == logLevelName)) - { - return FALSE; - } - - rdk_dbg_priv_SetLogLevelString(moduleName, logLevelName); - - int number = rdk_logger_envGetNum(moduleName); - if (WANT_LOG(number, logLevel)) + if(IS_LOGGING_ENABLED_FOR_LEVEL(module, level)) { return TRUE; } @@ -500,162 +387,110 @@ rdk_logger_Bool rdk_logger_enable_logLevel(const char *moduleName, rdk_LogLevel { return FALSE; } - -} - -/** - * Provides an interface to query the configuration of logging in a - * specific module as a user readable string. Note: the mimimum - * acceptable length of the supplied configuration buffer is 32 bytes. - * - * @param modName Name of the module. - * - * @param cfgStr The configuration strng: which should be space - * separated module names. - * - * @param cfgStrMaxLen The maximum length of the configuration string - * to be returned including the NUL character. - * - * @return A string containing a user readable error message if an - * error occured; or "OK" upon success. - */ -const char * rdk_dbg_priv_LogQueryOpSysIntf(char *modName, char *cfgStr, - int cfgStrMaxLen) -{ - char *name = modName; - int mod = -1; - uint32_t modCfg = 0; - int level = -1; - - assert(modName); - assert(cfgStr); - assert(cfgStrMaxLen > 32); - - cfgStrMaxLen -= 1; /**< Ensure there is space for NUL. */ - strncpy(cfgStr,"",cfgStrMaxLen); - - /** Get the module configuration. Note: DEFAULT is not valid as it - * is an alias. - */ - forceUpperCase(name); - mod = rdk_logger_envGetNum(modName); - if (mod < 0) - { - return "Unknown module specified."; - } - modCfg = rdk_g_logControlTbl[mod]; - - /** Try and find a succinct way of describing the configuration. */ - - if (modCfg == 0) - { - strncpy(cfgStr,"NONE",cfgStrMaxLen); - return "OK"; /* This is a canonical response. */ - } - - /** Loop through the control word and print out the enabled levels. */ - - for (level = 0; level < ENUM_RDK_LOG_COUNT; level++) - { - if (modCfg & (1 << level)) - { - /** Stop building out the config string if it would exceed - * the buffer length. - */ - if (strlen(cfgStr) + strlen(rdk_logLevelStrings[level]+1) - > (size_t) cfgStrMaxLen) - { - return "Warning: Config string too long, config concatenated."; - } - - strncat(cfgStr," ",cfgStrMaxLen); /* Not efficient - rah rah. */ - strncat(cfgStr,rdk_logLevelStrings[level],cfgStrMaxLen); - } - } - - return "OK"; } -void rdk_debug_priv_log_msg( rdk_LogLevel level, - int module, const char *module_name, const char* format, va_list args) +void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args) { /** Get the category from module name */ - static log4c_category_t *cat_cache[RDK_MAX_MOD_COUNT] = {NULL}; char cat_name[64] = {'\0'}; log4c_category_t* cat = NULL; + int prio = 0; /* Handling process request here. This is not a blocking call and it shall return immediately */ - rdk_dyn_log_processPendingRequest(); + rdk_dyn_log_process_pending_request(); - if (!g_debugEnabled || !WANT_LOG(module, level)) + cat = log4c_category_get(module_name); + prio = log4c_category_get_priority(cat); + if (cat && prio == LOG4C_PRIORITY_NOTSET && gRootCat) { + log4c_category_set_priority(cat, gRootPriority); + prio = gRootPriority; + } + + if(!cat) { - return; + cat = gRootCat; } - char *parent_cat_name = (char *)log4c_category_get_name(stackCat); - snprintf(cat_name, sizeof(cat_name)-1, "%s.%s", parent_cat_name == NULL ? "" : parent_cat_name, module_name); - - if((module >= 0) && (module < RDK_MAX_MOD_COUNT)) + if(!cat) { - if (cat_cache[module] == NULL) { - /** Only doing a read here, lock not needed */ - cat_cache[module] = log4c_category_get(cat_name); - } - - cat = cat_cache[module]; + return; } - /* CID :19939-- some function when explicitly call this function, it might have module < 0, then the else condition will be applicable*/ - else + + if (!IS_LOGGING_ENABLED_FOR_LEVEL(module_name, level)) { - cat = log4c_category_get(cat_name); + return; } switch (level) { - case RDK_LOG_FATAL: - log4c_category_vlog(cat, LOG4C_PRIORITY_FATAL, format, args); - break; - case RDK_LOG_ERROR: - log4c_category_vlog(cat, LOG4C_PRIORITY_ERROR, format, args); - break; - case RDK_LOG_WARN: - log4c_category_vlog(cat, LOG4C_PRIORITY_WARN, format, args); - break; - case RDK_LOG_NOTICE: - log4c_category_vlog(cat, LOG4C_PRIORITY_NOTICE, format, args); - break; - case RDK_LOG_INFO: - log4c_category_vlog(cat, LOG4C_PRIORITY_INFO, format, args); - break; - case RDK_LOG_DEBUG: - log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); - break; - case RDK_LOG_TRACE: - log4c_category_vlog(cat, LOG4C_PRIORITY_TRACE, format, args); - break; - default: - log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); - break; + case RDK_LOG_FATAL: + log4c_category_vlog(cat, LOG4C_PRIORITY_FATAL, format, args); + break; + case RDK_LOG_ERROR: + log4c_category_vlog(cat, LOG4C_PRIORITY_ERROR, format, args); + break; + case RDK_LOG_WARN: + log4c_category_vlog(cat, LOG4C_PRIORITY_WARN, format, args); + break; + case RDK_LOG_NOTICE: + log4c_category_vlog(cat, LOG4C_PRIORITY_NOTICE, format, args); + break; + case RDK_LOG_INFO: + log4c_category_vlog(cat, LOG4C_PRIORITY_INFO, format, args); + break; + case RDK_LOG_DEBUG: + log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); + break; + case RDK_LOG_TRACE: + log4c_category_vlog(cat, LOG4C_PRIORITY_TRACE, format, args); + break; + default: + log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); + break; } } -void RDK_LOG_ControlCB(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) +void rdk_dbg_priv_reconfig(const char *pModuleName, const char *pLogLevel) { char logTypeName[20] = {'\0'}; - if ((NULL == moduleName) || (NULL == loggingLevel)) + if ((NULL == pModuleName) || (NULL == pLogLevel)) { return; } - strncpy(logTypeName, loggingLevel, sizeof(logTypeName)-1); + strncpy(logTypeName, pLogLevel, sizeof(logTypeName)-1); if (logTypeName[0] == '~') { logTypeName[0] = '!'; } - rdk_dbg_priv_SetLogLevelString(moduleName, (const char *)logTypeName); + int disable = 0; + if (logTypeName[0] == '!') { + disable = 1; + memmove(logTypeName, logTypeName + 1, strlen(logTypeName)); + } + + int prio = LOG4C_PRIORITY_INFO; // default + if (strcasecmp(logTypeName, "FATAL") == 0) prio = LOG4C_PRIORITY_FATAL; + else if (strcasecmp(logTypeName, "ERROR") == 0) prio = LOG4C_PRIORITY_ERROR; + else if (strcasecmp(logTypeName, "WARNING") == 0) prio = LOG4C_PRIORITY_WARN; + else if (strcasecmp(logTypeName, "NOTICE") == 0) prio = LOG4C_PRIORITY_NOTICE; + else if (strcasecmp(logTypeName, "INFO") == 0) prio = LOG4C_PRIORITY_INFO; + else if (strcasecmp(logTypeName, "DEBUG") == 0) prio = LOG4C_PRIORITY_DEBUG; + else if (strcasecmp(logTypeName, "TRACE") == 0) prio = LOG4C_PRIORITY_TRACE; + else if (strcasecmp(logTypeName, "NONE") == 0) prio = LOG4C_PRIORITY_NONE; + + log4c_category_t* cat = log4c_category_get(pModuleName); + if (cat) { + if (disable) { + log4c_category_set_priority(cat, gRootPriority); + } + else { + log4c_category_set_priority(cat, prio); + } + } } @@ -685,11 +520,6 @@ static int initLogger(char *category) fprintf(stderr, "log4c_init() failed?!"); return -1; } - else - { - defaultCategory = log4c_category_get(category); - glibCategory = log4c_category_get("RI.GLib"); - } return 0; } @@ -1008,6 +838,3 @@ static int stream_env_close(log4c_appender_t* appender) return fclose(fp); } - -/*************************End Copied from ri_log.c******************/ - diff --git a/src/rdk_dynamic_logger.c b/src/rdk_dynamic_logger.c index e768659..c30f5f7 100644 --- a/src/rdk_dynamic_logger.c +++ b/src/rdk_dynamic_logger.c @@ -63,12 +63,14 @@ static char * rdk_dyn_log_logLevelToString(unsigned char log_level) return (negate) ? "!DEBUG":"DEBUG"; case RDK_LOG_TRACE: return (negate) ? "!TRACE":"TRACE"; + case RDK_LOG_NONE: + return "NONE"; } return NULL; } -static void rdk_dyn_log_validateComponentName(const unsigned char *buf) +static void rdk_dyn_log_validate_component_name(const unsigned char *buf) { unsigned char log_level = 0; int app_len, comp_len, i = DL_SIGNATURE_LEN; @@ -92,12 +94,12 @@ static void rdk_dyn_log_validateComponentName(const unsigned char *buf) loggingLevel = rdk_dyn_log_logLevelToString(log_level); if(NULL != loggingLevel) { memcpy(comp_name,buf+(++i),comp_len); - RDK_LOG_ControlCB(comp_name, NULL, loggingLevel, 0); + rdk_dbg_priv_reconfig(comp_name, loggingLevel); fprintf(stderr,"%s(): Set %s loglevel for the component %s of the process %s\n",__func__,loggingLevel,comp_name,__progname); } } -void rdk_dyn_log_processPendingRequest() +void rdk_dyn_log_process_pending_request() { char buf[128] = {0}; struct sockaddr_in sender_addr; @@ -107,7 +109,6 @@ void rdk_dyn_log_processPendingRequest() if(-1 == g_dl_socket) return; - memset(&sender_addr,0,sizeof(sender_addr)); while(1) { FD_ZERO(&rfds); @@ -140,7 +141,7 @@ void rdk_dyn_log_processPendingRequest() */ if((0 == strcmp("127.0.0.1",inet_ntoa(sender_addr.sin_addr))) && (numbytes == buf[4]+DL_SIGNATURE_LEN+1)) { - rdk_dyn_log_validateComponentName(buf); + rdk_dyn_log_validate_component_name(buf); } } } @@ -177,30 +178,9 @@ void rdk_dyn_log_init() fprintf(stderr, "%sg_dl_socket = %d __progname = %s \n",__func__,g_dl_socket,__progname); } -void rdk_dyn_log_deInit() +void rdk_dyn_log_deinit() { close(g_dl_socket); g_dl_socket = -1; } -char* rdk_loglevelToString(unsigned char log_level, rdk_LogLevel isLogEnabled) -{ - switch(log_level){ - case RDK_LOG_FATAL: - return (isLogEnabled) ? "FATAL":"!FATAL"; - case RDK_LOG_ERROR: - return (isLogEnabled) ? "ERROR":"!ERROR"; - case RDK_LOG_WARN: - return (isLogEnabled) ? "WARNING":"!WARNING"; - case RDK_LOG_NOTICE: - return (isLogEnabled) ? "NOTICE":"!NOTICE"; - case RDK_LOG_INFO: - return (isLogEnabled) ? "INFO":"!INFO"; - case RDK_LOG_DEBUG: - return (isLogEnabled) ? "DEBUG":"!DEBUG"; - case RDK_LOG_TRACE: - return (isLogEnabled) ? "TRACE":"!TRACE"; - } - - return NULL; -} diff --git a/src/rdk_logger_init.c b/src/rdk_logger_init.c index ceff225..8ad825d 100644 --- a/src/rdk_logger_init.c +++ b/src/rdk_logger_init.c @@ -67,28 +67,19 @@ rdk_Error rdk_logger_init(const char* debugConfigFile) debugConfigFile = DEBUG_CONF_FILE; } - ret = rdk_logger_env_add_conf_file(debugConfigFile); + /* Read the config file & populate pre-configured log levels */ + ret = rdk_logger_parse_config(debugConfigFile); if ( RDK_SUCCESS != ret) { printf("%s:%d Adding debug config file %s failed\n", __FUNCTION__, __LINE__, debugConfigFile); return ret; } + /* Perform Logger Internal Init */ + rdk_dbg_init(); - rdk_dbgInit(); + /* Perform Dynamin Logger Internal Init */ rdk_dyn_log_init(); - snprintf(buf, BUF_LEN-1, "/tmp/%s", "debugConfigFile_read"); - buf[BUF_LEN-1] = '\0'; - - if((0 == stat(buf, &st) && (0 != st.st_ino))) - { - printf("%s %s Already Stack Level Logging processed... not processing again.\n", __FUNCTION__, debugConfigFile); - } - else - { - rdk_dbgDumpLog(buf); - } - /** * Requests not to send SIGPIPE on errors on stream oriented * sockets when the other end breaks the connection. The EPIPE @@ -100,6 +91,17 @@ rdk_Error rdk_logger_init(const char* debugConfigFile) return RDK_SUCCESS; } +rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config) + { + rdk_Error ret; + ret = RDK_LOGGER_INIT(); + if (ret == RDK_SUCCESS) + { + rdk_dbg_priv_ext_init(config->logdir, config->fileName, config->maxCount, config->maxSize); + } + return ret; + } + /** * @brief Cleanup the logger instantiation. * @@ -109,11 +111,8 @@ rdk_Error rdk_logger_deinit() { if(isLogInited) { - //rdk_dbgDeinit(); - rdk_dyn_log_deInit(); - //rdk_dbg_priv_DeInit(); - rdk_logger_env_rem_conf_details(); - log4c_fini(); + rdk_dyn_log_deinit(); + rdk_logger_release_config(); //isLogInited = 0; } diff --git a/src/rdk_logger_util.c b/src/rdk_logger_util.c index d25b119..b95a671 100644 --- a/src/rdk_logger_util.c +++ b/src/rdk_logger_util.c @@ -38,7 +38,7 @@ #include /*Resolve reboot and related macros.*/ -#include +#include #include #include @@ -93,7 +93,7 @@ static void trim(char *instr, char* outstr) * * @return Returns Returns RDK_SUCCESS if the setting of environment variable is successful else it returns -1. */ -rdk_Error rdk_logger_env_rem_conf_details() +rdk_Error rdk_logger_release_config() { EnvVarNode *currentNode; EnvVarNode *nextNode; @@ -122,7 +122,7 @@ rdk_Error rdk_logger_env_rem_conf_details() * @param[in] path Path of the configuration file. * @return Returns Returns RDK_SUCCESS if the setting of environment variable is successful else it returns -1. */ -rdk_Error rdk_logger_env_add_conf_file( const char * path) +rdk_Error rdk_logger_parse_config( const char * path) { const int line_buf_len = 256; @@ -174,7 +174,7 @@ rdk_Error rdk_logger_env_add_conf_file( const char * path) /* Trim all whitespace from name and value strings */ trim( name,trimname); trim( value,trimvalue); - + tmp_node = g_envCache; while(tmp_node) { @@ -182,9 +182,9 @@ rdk_Error rdk_logger_env_add_conf_file( const char * path) { break; } - tmp_node = tmp_node->next; - } - + tmp_node = tmp_node->next; + } + if(!tmp_node) { node = ( EnvVarNode*)malloc(sizeof(EnvVarNode)); @@ -198,14 +198,15 @@ rdk_Error rdk_logger_env_add_conf_file( const char * path) continue; } +#define COMP_SIGNATURE "LOG.RDK." +#define COMP_SIGNATURE_LEN 8 /** Update number only for the modules, not for environment variable */ - if ((strcmp("LOG.RDK.DEFAULT",node->name) != 0) && - (strcmp("EnableMPELog",node->name) != 0) && - (strcmp("SEPARATE.LOGFILE.SUPPORT",node->name) != 0)) + if ((strcmp("LOG.RDK.DEFAULT", node->name) != 0) && + (strncmp(COMP_SIGNATURE, node->name, COMP_SIGNATURE_LEN) == 0)) { - number++; - node->number = number; - } else + number++; + node->number = number; + } else node->number = 0; /* Insert at the front of the list */ @@ -256,11 +257,11 @@ const char* rdk_logger_envGet(const char *name) * variable or return NULL in failure condition. */ const char* rdk_logger_envGetValueFromNum(int number) -{ +{ EnvVarNode *node = g_envCache; while (node != NULL) - { + { /* Env var name match */ if (number == node->number) { @@ -329,3 +330,28 @@ const char* rdk_logger_envGetModFromNum(int Num) return NULL; } +char* rdk_loglevelToString(rdk_LogLevel log_level, rdk_logger_Bool isLogEnabled) +{ + switch(log_level){ + case RDK_LOG_FATAL: + return (isLogEnabled) ? "FATAL":"!FATAL"; + case RDK_LOG_ERROR: + return (isLogEnabled) ? "ERROR":"!ERROR"; + case RDK_LOG_WARN: + return (isLogEnabled) ? "WARNING":"!WARNING"; + case RDK_LOG_NOTICE: + return (isLogEnabled) ? "NOTICE":"!NOTICE"; + case RDK_LOG_INFO: + return (isLogEnabled) ? "INFO":"!INFO"; + case RDK_LOG_DEBUG: + return (isLogEnabled) ? "DEBUG":"!DEBUG"; + case RDK_LOG_TRACE: + return (isLogEnabled) ? "TRACE":"!TRACE"; + } + + return NULL; +} + + + +/***/ diff --git a/unittests/rdkIsDbgEnabled.cpp b/unittests/rdkIsDbgEnabled.cpp index 4033714..2ebc96b 100644 --- a/unittests/rdkIsDbgEnabled.cpp +++ b/unittests/rdkIsDbgEnabled.cpp @@ -23,9 +23,9 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include "rdk_debug.h" -#include "rdk_utils.h" #include "gtest_app.h" +#if 0 TEST(rdkIsDbgEnabled, ONLYFATAL_log_enabled) { @@ -682,4 +682,4 @@ TEST(rdkIsDbgEnabled, ALLLOGLEVELS_log_enabled) //ret = rdk_logger_deinit(); //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< Log Level of the Component to be modified\n"); - printf(" Possible values - FATAL,ERROR,WARN,NOTICE,INFO,DEBUG,TRACE\n"); + printf(" Possible values - FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE, NONE\n"); printf(" Turn off any loglevel using '~' symbol.\n"); printf(" (i.e) '~ERROR' would turn off error logs alone for that component\n"); } -static char validate_loglevel(const char* level) +static int validate_loglevel(const char* level) { char *loglevel = (char *)level; - char negate = 0; + unsigned char negate = 0; if(loglevel[0] == '~') { loglevel++; negate = 0x80; } - if(0 == strncmp(loglevel,"FATAL",5)) + if(0 == strncmp(loglevel, "FATAL", 5)) return negate|RDK_LOG_FATAL; - else if(0 == strncmp(loglevel,"ERROR",5)) + else if(0 == strncmp(loglevel, "ERROR", 5)) return negate|RDK_LOG_ERROR; - else if(0 == strncmp(loglevel,"WARN",4)) + else if(0 == strncmp(loglevel, "WARN", 4)) return negate|RDK_LOG_WARN; - else if(0 == strncmp(loglevel,"NOTICE",6)) + else if(0 == strncmp(loglevel, "NOTICE", 6)) return negate|RDK_LOG_NOTICE; - else if(0 == strncmp(loglevel,"INFO",4)) + else if(0 == strncmp(loglevel, "INFO", 4)) return negate|RDK_LOG_INFO; - else if(0 == strncmp(loglevel,"DEBUG",5)) + else if(0 == strncmp(loglevel, "DEBUG", 5)) return negate|RDK_LOG_DEBUG; - else if(0 == strncmp(loglevel,"TRACE",6)) + else if(0 == strncmp(loglevel, "TRACE", 6)) return negate|RDK_LOG_TRACE; + else if(0 == strncmp(loglevel, "NONE", 4)) + return RDK_LOG_NONE; else - return ENUM_RDK_LOG_COUNT; + return -1; } static int validate_module_name(const char *name) @@ -86,7 +88,7 @@ int main(int argc, char *argv[]) { struct sockaddr_in dest_addr; int i, sockfd, numbytes, addr_len, app_len, comp_len, optval = 1; - char level = -1; + int level = -1; unsigned char buf[128] = {0}; if (argc != 4) { @@ -95,8 +97,8 @@ int main(int argc, char *argv[]) } if(0 != strcmp("Receiver",argv[1])) { - if( (0 != strncmp(argv[2],COMP_SIGNATURE,COMP_SIGNATURE_LEN)) || - (0 != validate_module_name(argv[2])) ) { + if( (0 != strncmp(argv[2],COMP_SIGNATURE,COMP_SIGNATURE_LEN))) + { printf("Invalid module name\n"); usage(argv[0]); return -1; @@ -104,7 +106,7 @@ int main(int argc, char *argv[]) } level = validate_loglevel(argv[3]); - if(ENUM_RDK_LOG_COUNT == level) { + if(-1 == level) { printf("Invalid log level\n"); usage(argv[0]); return -1; From 50bee88cd85d282983b540d1ccbf8e4d71df77e6 Mon Sep 17 00:00:00 2001 From: Karunakaran A Date: Tue, 5 Aug 2025 23:22:40 -0400 Subject: [PATCH 05/37] Release of RDKLogger v2.0.0 Release of RDKLogger v2.0.0 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6bf1139..146a1f4 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 1.0, balaji_punnuru@cable.comcast.com,rmfwebkitifc) +AC_INIT(rdklogger, 2.0.0) AC_CONFIG_SRCDIR([src]) AM_CONFIG_HEADER(cfg/config.h) AC_CONFIG_MACRO_DIR([cfg]) From efe9c4ef9ac6e28fceebfa84d74019b5e247f93c Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Wed, 6 Aug 2025 08:47:42 +0530 Subject: [PATCH 06/37] RDKEMW-6709: RDKLogger - Refactoring (#19) Reason for change: Refactor the RDKLogger component in such a way that, 1. The config file debug.ini is only for the override; 2. Must log even if new module not present in debug.ini 3. The config file must say only the specific level; not individual log levels 4. Default loglevel must be based on LOG.RDK.DEFAULT 5. Remove log4crc overrides Test Procedure: Tested and verified Risks: Medium Signed-off-by: dshett549 Signed-off-by: Karunakaran A Co-authored-by: Karunakaran A <48997923+karuna2git@users.noreply.github.com> --- README.md | 38 +- build.sh | 108 ----- debug.ini | 149 +------ debug.ini.sample | 33 ++ include/Makefile.am | 2 +- include/rdk_debug.h | 153 ++++--- log4crc | 177 +------- rdkb_debug.ini | 98 ----- rdkb_debug_arm.ini | 58 --- rdkb_debug_atom.ini | 43 -- rdkb_log4crc | 517 ----------------------- rdkb_log4crc_arm | 312 -------------- rdkb_log4crc_atom | 220 ---------- rdkc_log4crc | 196 --------- src/include/rdk_debug_priv.h | 51 +-- src/include/rdk_dynamic_logger.h | 8 +- {include => src/include}/rdk_utils.h | 6 +- src/rdk_debug.c | 114 ++---- src/rdk_debug_priv.c | 587 ++++++++++----------------- src/rdk_dynamic_logger.c | 34 +- src/rdk_logger_init.c | 37 +- src/rdk_logger_util.c | 56 ++- unittests/rdkIsDbgEnabled.cpp | 4 +- utils/rdklogctrl.c | 32 +- 24 files changed, 522 insertions(+), 2511 deletions(-) delete mode 100755 build.sh create mode 100644 debug.ini.sample delete mode 100644 rdkb_debug.ini delete mode 100644 rdkb_debug_arm.ini delete mode 100644 rdkb_debug_atom.ini delete mode 100644 rdkb_log4crc delete mode 100644 rdkb_log4crc_arm delete mode 100644 rdkb_log4crc_atom delete mode 100644 rdkc_log4crc rename {include => src/include}/rdk_utils.h (88%) diff --git a/README.md b/README.md index 29d49bb..43ab6ec 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,36 @@ -Overview: ---------- +# RDK Logger -The rdklogger is a general-purpose logging mechanism that utilizes log4c for formatting and supports multiple log levels and modules. The log level for each module is read from a configuration file (debug.ini, typically located at /etc/debug.ini) at startup, where log modules and their enabled log levels are defined. +RDK Logger is a general-purpose logging mechanism for RDK components. It supports multiple log levels and modules, with log levels configured via a configuration file (`debug.ini`). Each module can have its own log level, and these can be changed at runtime using the provided CLI utility. -rdklogger supports overriding the configuration at runtime by providing a persistent path to files like /opt/debug.ini or /nvram/debug.ini. It includes a CLI utility called rdklogctrl, which is used to dynamically change log levels for modules at runtime. +## Features -Internally, rdklogger leverages log4c for its formatting, log writing, and log rotation capabilities. One unique feature of rdklogger is that you do not set a single severity level above which no logs with greater severity would be logged. Instead, each level (ERROR, WARN, INFO, DEBUG, etc.) can be independently enabled or disabled. This means you could, for example, disable all ERROR logs while enabling all DEBUG logs. +- Abstracts logging client from underlying logging utility. +- Dynamically enables/disables logging level at run time. +- Provides a structured log format including timestamp, module name, log level, and message. +- Controls log level independently for each component/module. +- Enables logging globally via a single configuration value. +- Controls initial log level for each component/module from configuration file (`debug.ini`) at startup. +- Prints formatted data to stdout or log files. +- Supports separate log files for each module if configured. + +## Configuration + +Logging levels and modules are configured in `debug.ini`. If a module is not explicitly configured in `debug.ini`, it inherits the log level from `LOG.RDK.DEFAULT`. + +See `debug.ini.sample` for an example configuration file. +The sample file includes comments explaining how to set log levels for each module and what each log level enables. + +For example: +``` +LOG.RDK.DEFAULT=WARNING +LOG.RDK.FOO=DEBUG +LOG.RDK.BAR=NONE +``` + +- The component `FOO` will print DEBUG, INFO, WARNING, ERROR, and FATAL messages +- The component `BAR` prints `nothing` +- All the other components prints WARNING and higher log levels like ERROR, and FATAL as defined by `DEFAULT` + +## Runtime Control + +Use the `rdklogctrl` utility to change log levels for modules at run time. diff --git a/build.sh b/build.sh deleted file mode 100755 index 5cbcf10..0000000 --- a/build.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/sh -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -# -PWD=`pwd` -export RDK_DIR=`echo $PWD/..` -source soc/build/soc_env.sh - - -copyLibs=0 -instalLibs=0 -setupSDK=0 -buildMode="build" -instaldir=build - -for option in $@ -do - echo option = $option - if [ "$option" = "clean" ]; then - buildMode="clean" - elif [ "$option" = "install" -o "$option" = "instal" ] ; then - instalLibs=1 - elif [ "$option" = "copy" ] ; then - copyLibs=1 - elif [ "$option" = "setup" ] ; then - setupSDK=1 - fi - - -done - -if [ $setupSDK -eq 1 ]; -then - echo $PLATFORM_SDK - if [ -d "$PLATFORM_SDK" ] - then - echo "toolchain is already installed..." - else - echo Installing toolchain, it may take few seconds depends on your system - tar zxf $RDK_DIR/sdk/toolchain/staging_dir.tgz -C $RDK_DIR/sdk/toolchain - echo "toolchain installed $PLATFORM_SDK" - fi - - echo $ROOTFS - if [ -d "$ROOTFS" ] - then - echo "ROOT FS is already extracted..." - else - echo extracting ROOT FS, it may take few seconds depends on your system - sudo tar zxf $RDK_DIR/sdk/fsroot/fsroot.tgz -C $RDK_DIR/sdk/fsroot - sudo tar zxf $RDK_DIR/sdk/fsroot/curl.tgz -C $RDK_DIR/sdk/fsroot - sudo tar zxf $RDK_DIR/sdk/fsroot/mafLib.tgz -C $RDK_DIR/sdk/fsroot - echo "ROOT FS is extracted $ROOTFS" - fi - -fi - -if [ "$buildMode" = "clean" ]; -then - echo "Cleaning the build and $instaldir" - make clean -fi - -if [ $copyLibs -ne 1 ] ; -then - echo ========================================================================================================================================================= - echo --------------------------BUILDING RDK LOGGER --------------------------------- - echo ========================================================================================================================================================= - make - if [ $? -ne 0 ] ; - then - echo RDK LOGGER build failed - exit -1 - fi - echo ======================================================================================================================================================== - echo --------------------------BUILDING RDK LOGGER DONE --------------------------------- - echo ======================================================================================================================================================== -fi - -if [ $instalLibs -eq 1 ]; -then - echo installing binaries.... - mkdir -p $instaldir/env - mkdir -p $ROOTFS/mnt/nfs/env - mkdir -p $ROOTFS/mnt/nfs/lib - - cp *.ini $instaldir/env - cp log4crc $instaldir/env - cp -a $instaldir/env/* $ROOTFS/mnt/nfs/env - mkdir -p $ROOTFS/usr/lib - cp -a $instaldir/lib/* $ROOTFS/usr/lib -fi diff --git a/debug.ini b/debug.ini index 5662cc0..dff0f90 100644 --- a/debug.ini +++ b/debug.ini @@ -16,151 +16,4 @@ # See the License for the specific language governing permissions and # limitations under the License. ########################################################################## -#### Logging #### - -EnableMPELog = TRUE - -SEPARATE.LOGFILE.SUPPORT=FALSE -LOG.RDK.DEFAULT = ERROR -LOG.RDK.TARGET = FATAL ERROR WARNING INFO -LOG.RDK.CC = FATAL ERROR WARNING INFO -LOG.RDK.CDL = FATAL ERROR WARNING INFO -LOG.RDK.SNMP = FATAL ERROR WARNING INFO -LOG.RDK.COND = NONE -LOG.RDK.DBG = NONE -LOG.RDK.DIRECTFB = NONE -LOG.RDK.DISP = FATAL ERROR INFO -LOG.RDK.DLL = NONE -LOG.RDK.DVR = FATAL ERROR WARNING INFO -LOG.RDK.REC = FATAL ERROR WARNING INFO -LOG.RDK.RBI = FATAL ERROR WARNING INFO -LOG.RDK.HN = FATAL ERROR INFO WARNING -LOG.RDK.GSTREAMER=ALL FATAL ERROR WARNING INFO DEBUG -LOG.RDK.HNSRC=ALL TRACE DEBUG FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MPSINK=ALL TRACE DEBUG FATAL ERROR WARNING NOTICE INFO -LOG.RDK.EVENT = FATAL ERROR -LOG.RDK.ED = NONE -LOG.RDK.FILESYS = FATAL ERROR WARNING INFO -LOG.RDK.FILTER = ERROR -LOG.RDK.FP = ALL INFO -LOG.RDK.GFX = ERROR -LOG.RDK.JAVA = ALL !INFO !DEBUG WARNING -LOG.RDK.JNI = !DEBUG !INFO WARNING ERROR TRACE -LOG.RDK.JVM = ALL INFO -LOG.RDK.MEDIA = FATAL ERROR WARNING INFO -LOG.RDK.MEM = NONE -LOG.RDK.MUTEX = NONE -LOG.RDK.NET = NONE -LOG.RDK.OS = FATAL ERROR WARNING -LOG.RDK.POD = FATAL ERROR WARNING INFO -LOG.RDK.SI = FATAL ERROR WARNING -LOG.RDK.INBSI = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.STORAGE = NONE -LOG.RDK.SYS = FATAL ERROR WARNING INFO -LOG.RDK.TEST = ALL DEBUG -LOG.RDK.THREAD = NONE -LOG.RDK.UTIL = NONE -LOG.RDK.UI = NONE -LOG.RDK.QAMSRC = ALL FATAL ERROR WARNING INFO -LOG.RDK.VODSRC = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MS = ALL FATAL ERROR WARNING INFO -LOG.RDK.GSTQAM = ALL FATAL ERROR WARNING INFO -LOG.RDK.IPPV = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.IPC = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PXYSRVC = FATAL ERROR WARNING INFO -LOG.RDK.RMFBASE = FATAL ERROR WARNING INFO -LOG.RDK.RDKBROWSER2 = FATAL ERROR WARNING INFO -LOG.RDK.TRM = NONE -LOG.RDK.IARMBUS = ALL DEBUG -LOG.RDK.DSMGR = ALL FATAL ERROR WARNING INFO !DEBUG -LOG.RDK.IRMGR = ALL DEBUG -LOG.RDK.MFRMGR = ALL DEBUG -LOG.RDK.POWERMGR = DEBUG -LOG.RDK.SYSMGR = ALL DEBUG -LOG.RDK.TR69MGR = ALL DEBUG -LOG.RDK.VREXMGR = ALL DEBUG -LOG.RDK.TRH = FATAL ERROR WARNING INFO -LOG.RDK.SDVAGENT = FATAL ERROR WARNING INFO -LOG.RDK.RF4CEMGR = FATAL ERROR WARNING INFO -LOG.RDK.LPRFSERVER = FATAL ERROR WARNING INFO -LOG.RDK.CEF = ALL FATAL ERROR WARNING NOTICE INFO DEBUG -LOG.RDK.WIFIWPA = ERROR WARNING INFO DEBUG -LOG.RDK.WIFIP2PWPA = ERROR WARNING INFO -LOG.RDK.NETSRVMGR = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WIFIHAL = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBPAVIDEO = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TR69HOSTIF = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.PARODUS = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.PARODUSIF = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.BTRMGR = ALL ERROR WARNING INFO -LOG.RDK.BTRCORE = ALL ERROR WARNING INFO -LOG.RDK.BTRLEMGR = ALL DEBUG FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CVR=ALL ERROR WARNING INFO -LOG.RDK.CVRUPLOAD=ALL ERROR WARNING INFO -LOG.RDK.CVRPOLL=ALL ERROR WARNING INFO -LOG.RDK.THUMBNAILUPLOAD=ALL ERROR WARNING INFO -LOG.RDK.SMARTTHUMBNAIL=ALL ERROR WARNING INFO -LOG.RDK.RMS=ALL ERROR WARNING INFO -LOG.RDK.METRICS=ALL ERROR WARNING INFO -LOG.RDK.PLUGINS=ALL ERROR WARNING INFO -LOG.RDK.WEBPA=ALL ERROR WARNING INFO -LOG.RDK.BINDING=ALL ERROR WARNING INFO -LOG.RDK.WRTC=ALL ERROR WARNING INFO -LOG.RDK.VIDEOANALYTICS=ALL ERROR WARNING INFO -LOG.RDK.AUDIOANALYTICS=ALL ERROR WARNING INFO -LOG.RDK.STORAGEMGR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.OVERLAY =ALL ERROR WARNING INFO -LOG.RDK.HTTPCLIENT=ALL ERROR WARNING INFO -LOG.RDK.CPUPROCANALYZER=ERROR WARNING INFO -LOG.RDK.XCV=ALL ERROR WARNING INFO -LOG.RDK.AKER = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.RTMESSAGE = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.RBUS = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.RBUSCORE = FATAL WARNING NOTICE INFO ERROR -LOG.RDK.DYNAMICLOG = ALL ERROR WARNING INFO -LOG.RDK.XWCONFIG = ALL FATAL ERROR WARNING INFO -LOG.RDK.LIBSYSCALLWRAPPER = ALL FATAL WARNING NOTICE INFO DEBUG ERROR -LOG.RDK.PRVNMGR = ALL FATAL ERROR WARNING INFO -LOG.RDK.SPDTST = ALL FATAL ERROR WARNING NOTICE INFO DEBUG TRACE -LOG.RDK.BREAKPAD=ALL FATAL ERROR WARNING INFO DEBUG -LOG.RDK.BLE=ALL FATAL ERROR WARNING INFO DEBUG -LOG.RDK.HWST = ERROR -LOG.RDK.IAVENCODER=ALL ERROR WARNING INFO -LOG.RDK.WEBCONFIG=ALL ERROR WARNING INFO -LOG.RDK.MQTTCM=ALL ERROR WARNING INFO -LOG.RDK.WATCHDOG=ALL ERROR WARNING INFO -LOG.RDK.SMARTRC=ALL FATAL ERROR WARNING INFO -LOG.RDK.XSTREAM=ALL FATAL ERROR WARNING INFO -LOG.RDK.XAUDIO=ALL FATAL ERROR WARNING INFO -LOG.RDK.XSENSOR=ALL FATAL ERROR WARNING INFO -LOG.RDK.BATTMGR = ALL FATAL ERROR WARNING INFO -LOG.RDK.BUTTONMGR = ALL FATAL ERROR WARNING INFO -LOG.RDK.ADVSEC = ALL FATAL WARNING NOTICE INFO DEBUG ERROR -LOG.RDK.XDNS = ALL FATAL ERROR WARNING NOTICE INFO DEBUG TRACE -LOG.RDK.XWBANDMON = ALL FATAL ERROR WARNING INFO -LOG.RDK.XWWATCHDOG = ALL FATAL ERROR WARNING INFO -LOG.RDK.SYSTIMEMGR = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCP = ALL FATAL ERROR WARNING NOTICE INFO DEBUG -LOG.RDK.T2 = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MEDIAPIPE = ALL ERROR WARNING INFO -LOG.RDK.FWUPG = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.REMOTEDEBUGGER = ALL FATAL WARNING NOTICE INFO DEBUG ERROR -LOG.RDK.RDKCPROVIDER = ALL ERROR WARNING INFO -LOG.RDK.WANCNCTVTYCHK = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.NLMON = ALL ERROR WARNING INFO FATAL -LOG.RDK.RFCMGR = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RFCAPI = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FLASHAPP = ALL FATAL ERROR WARNING INFO -LOG.RDK.DCM = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RDKSSACERTCHECK = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RDM = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LXY = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.IPCONTROL = ALL FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RDKSSADAEMON = ERROR WARNING -LOG.RDK.LNF = ALL FATAL ERROR WARNING NOTICE INFO DEBUG TRACE -LOG.RDK.CERTSELECTOR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.NFRTOOL = ALL FATAL ERROR WARNING INFO DEBUG -LOG.RDK.SUBS.REND = FATAL ERROR WARNING INFO -LOG.RDK.SUBS.GFX = FATAL ERROR WARNING INFO -LOG.RDK.SUBS.CORE = FATAL ERROR WARNING INFO -LOG.RDK.MFRHAL = ALL FATAL ERROR WARNING INFO +LOG.RDK.DEFAULT = INFO diff --git a/debug.ini.sample b/debug.ini.sample new file mode 100644 index 0000000..38a0e41 --- /dev/null +++ b/debug.ini.sample @@ -0,0 +1,33 @@ +########################################################################## +# debug.ini.sample - Example configuration for RDK Logger +# +# Each line sets the logging level for a module. +# Format: +# LOG.RDK.= +# +# Log levels (from most to least verbose): +# TRACE - Enables TRACE, DEBUG, INFO, NOTICE, WARN, ERROR, FATAL +# DEBUG - Enables DEBUG, INFO, NOTICE, WARN, ERROR, FATAL +# INFO - Enables INFO, NOTICE, WARN, ERROR, FATAL +# NOTICE - Enables NOTICE, WARN, ERROR, FATAL +# WARN - Enables WARN, ERROR, FATAL +# ERROR - Enables ERROR, FATAL +# FATAL - Enables FATAL only +# +# LOG.RDK.DEFAULT sets the default log level for all modules not explicitly listed. +########################################################################## + +LOG.RDK.DEFAULT=WARNING +# All modules not listed (no override) will log WARN, ERROR, and FATAL messages + +#LOG.RDK.TEST=DEBUG +# Enables DEBUG and all higher-severity logs (INFO, NOTICE, WARN, ERROR, FATAL) for LOG.RDK.TEST + +#LOG.RDK.SAMPLE=INFO +# Enables INFO and all higher-severity logs (NOTICE, WARN, ERROR, FATAL) for LOG.RDK.SAMPLE + +LOG.RDK.FOO=INFO +# LOG.RDK.FOO will log INFO, NOTICE, WARN, ERROR, and FATAL messages + +LOG.RDK.BAR = NONE +#ALL logs will be disabled for this module diff --git a/include/Makefile.am b/include/Makefile.am index 420a9ba..5407b1e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -19,4 +19,4 @@ SUBDIRS = librdkloggers_la_includedir = $(includedir) -librdkloggers_la_include_HEADERS = rdk_debug.h rdk_error.h rdk_logger_types.h rdk_utils.h rdk_logger_milestone.h +librdkloggers_la_include_HEADERS = rdk_debug.h rdk_error.h rdk_logger_types.h rdk_logger_milestone.h diff --git a/include/rdk_debug.h b/include/rdk_debug.h index ded4017..5234991 100644 --- a/include/rdk_debug.h +++ b/include/rdk_debug.h @@ -116,13 +116,13 @@ * @par Logging Levels supported by RDK Logger. * Code | Description * -----|------------ - * RDK_LOG_FATAL | Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss), reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss. - * RDK_LOG_ERROR | Any error which is fatal to the operation but not the service (cant open a file, missing data, etc) - * RDK_LOG_WARN | Anything that can potentially cause application oddities, but for which the application automatically recoverring. - * RDK_LOG_NOTICE | Anything that largely superfluous for application-level logging. - * RDK_LOG_INFO | Generally useful information to log (service start/stop, configuration assumptions, etc). - * RDK_LOG_DEBUG | Information that is diagnostically helpful to people more than just developers. - * RDK_LOG_TRACE | Only when it would be "tracing" the code and trying to find one part of a function specifically. + * RDK_LOG_FATAL | Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss), reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss. + * RDK_LOG_ERROR | Any error which is fatal to the operation but not the service (cant open a file, missing data, etc) + * RDK_LOG_WARN | Anything that can potentially cause application oddities, but for which the application automatically recoverring. + * RDK_LOG_NOTICE | Anything that largely superfluous for application-level logging. + * RDK_LOG_INFO | Generally useful information to log (service start/stop, configuration assumptions, etc). + * RDK_LOG_DEBUG | Information that is diagnostically helpful to people more than just developers. + * RDK_LOG_TRACE | Only when it would be "tracing" the code and trying to find one part of a function specifically. * * @par How log files are upload to server * @image html rdk_logupload.jpg @@ -159,13 +159,25 @@ extern "C" /** * Macros for ease of applications using RDK_LOGGER apis */ + +/** + * Define the default location of configuration file location + */ +#define DEBUG_INI_NAME "/etc/debug.ini" + /** * Support for overriding debug.ini file location */ -#define DEBUG_INI_OVERRIDE_PATH "/opt/debug.ini" -#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ - ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ - : rdk_logger_init(DEBUG_INI_NAME); +#ifndef DEBUG_INI_OVERRIDE_PATH +#define DEBUG_INI_OVERRIDE_PATH "/nvram/debug.ini" +#endif + +/** + * Support for Init function + */ +#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ + ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ + : rdk_logger_init(DEBUG_INI_NAME); /** * Use RDK_LOG debug message as. * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) @@ -176,30 +188,18 @@ extern "C" #define RDK_LOG rdk_logger_msg_printf #define RDK_LOG1 rdk_logger_msg_vsprintf - /** - * @enum rdk_LogLevel - * @brief These values represent the logging 'levels' or 'types', they are each - * independent. + * Define the max length for the log file capture */ -typedef enum -{ - ENUM_RDK_LOG_BEGIN = 0, /**< Used as array index. */ +#define RDK_LOGGER_EXT_FILENAME_SIZE 32 - RDK_LOG_FATAL = ENUM_RDK_LOG_BEGIN, - RDK_LOG_ERROR, - RDK_LOG_WARN, - RDK_LOG_NOTICE, - RDK_LOG_INFO, - RDK_LOG_DEBUG, - - RDK_LOG_TRACE, - - ENUM_RDK_LOG_COUNT -} rdk_LogLevel; +/** + * Define the max length for the log capture path + */ +#define RDK_LOGGER_EXT_LOGDIR_SIZE 32 /** - * To allow compatibility of mutiple rdke components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 and function rdk_dbg_enabled + * To allow compatibility of mutiple legacy RDK components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 */ #define RDK_LOG_TRACE1 RDK_LOG_TRACE #define RDK_LOG_TRACE2 RDK_LOG_TRACE @@ -211,47 +211,98 @@ typedef enum #define RDK_LOG_TRACE8 RDK_LOG_TRACE #define RDK_LOG_TRACE9 RDK_LOG_TRACE +/** + * An access function macro to check logging is enabled or not + */ #define rdk_dbg_enabled rdk_logger_is_logLevel_enabled /** - * String names that correspond to the various logging types. - * Note: This array *must* match the RDK_LOG_* enum. + * @enum rdk_LogLevel + * @brief These values represent the logging 'levels' or 'types', they are each + * independent. */ -#ifdef RDK_DEBUG_DEFINE_STRINGS -const char *rdk_logLevelStrings[ENUM_RDK_LOG_COUNT] = +typedef enum { - "FATAL", - "ERROR", - "WARNING", - "NOTICE", - "INFO", - "DEBUG", + RDK_LOG_FATAL = 0, + RDK_LOG_ERROR, + RDK_LOG_WARN, + RDK_LOG_NOTICE, + RDK_LOG_INFO, + RDK_LOG_DEBUG, + RDK_LOG_TRACE, + RDK_LOG_NONE +} rdk_LogLevel; - "TRACE", -}; -#endif /* RDK_DEBUG_DEFINE_STRINGS */ +typedef struct rdk_logger_ext_config_t + { + char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; + char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; + long maxSize; + long maxCount; + }rdk_logger_ext_config_t; /** - * @ingroup RDKLOGGER_DEBUG_API - * @{ + * @brief Initialize the RDK Logger. + * @param debugConfigFile Path to the debug.ini configuration file. + * @return RDK_SUCCESS on success, error code otherwise. */ - rdk_Error rdk_logger_init(const char* debugConfigFile); -rdk_Error rdk_logger_deinit(); +/** + * @brief Extended initialization for RDK Logger. + * @param config Pointer to rdk_logger_ext_config_t structure. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config); -void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +/** + * @brief Deinitialize the RDK Logger. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_deinit(void); -void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module,const char *format, va_list args); +/** + * @brief Log a message with printf-style formatting. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + */ +void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...); +/** + * @brief Log a message using a va_list. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + * @param args va_list of arguments. + */ +void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args); + +/** + * @brief Check if a log level is enabled for a module. + * @param module Module name. + * @param level Log level. + * @return TRUE if enabled, FALSE otherwise. + */ rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); +/** + * @brief Enable or disable a log level for a module. + * @param module Module name. + * @param logLevel Log level. + * @param enableLogLvl TRUE to enable, FALSE to disable. + * @return TRUE if successful, FALSE otherwise. + */ rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); +/** + * @brief Log a message for onboard logging. + * @param module Module name. + * @param msg Message to log. + */ void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribute__ ((format (printf, 2, 3))); -/** @} */ //end of Doxygen tag RDKLOGGER_DEBUG_API - +/** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API #ifdef __cplusplus } diff --git a/log4crc b/log4crc index 0bf7322..67f35fe 100644 --- a/log4crc +++ b/log4crc @@ -1,184 +1,39 @@ - - - - - - 0 - - 0 - 0 - - - - - - - - - - - - - - - - - - + 0 - + - - - - - - - - - - - + 0 - + 0 - + - - - - - - - - - + - - - - - - - - - - - - - - + - - + - + - - - - - + - + diff --git a/rdkb_debug.ini b/rdkb_debug.ini deleted file mode 100644 index 7c4a908..0000000 --- a/rdkb_debug.ini +++ /dev/null @@ -1,98 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#### Logging #### - -EnableMPELog = TRUE - -SEPARATE.LOGFILE.SUPPORT=FALSE -LOG.RDK.DEFAULT = WARNING -LOG.RDK.RTMESSAGE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TR69 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PAM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PSM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MOCA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MTA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TDM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WIFI = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMRXM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMBRG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMRBP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMMON = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SSD = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FU = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.IMAGEHEALTHCHECKER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Misc = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SNMP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBPA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Harvester = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.HOTSPOT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCPSNOOP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.NOTIFY = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WECB = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WECBMASTER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XSMART = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TOUCHSTONE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FSC = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PWRMGR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MESH = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.T2 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MeshService = FATAL ERROR WARNING NOTICE INFO DEBUG TRACE -LOG.RDK.ETHAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCPMGR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GWPROV = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Seshat = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PARODUS = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.AKER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GWPROVETHWAN = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GWPROVGPONWAN = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LIBSYSCALLWRAPPER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SPDTST = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BLE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BTRCORE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BTRMGR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WANAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TELCOVOIPAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBCONFIG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MQTTCM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.ADVSEC = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XDNS = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DSLAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.VLANAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XTMAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CERTSELECTOR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CPUPROCANALYZER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.HWST = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.OVSAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WANMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WANCNCTVTYCHK = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MAPTLOG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.VLANMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GPONMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FWUPGRADEMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BATTERYMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CELLULARMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.INTERDEVICEMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GATEWAYMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LANMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PLATFORMMANAGER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.EASYMESHCTL = FATAL ERROR WARNING INFO -LOG.RDK.WEBCONFIGRFC = FATAL ERROR WARNING NOTICE INFO diff --git a/rdkb_debug_arm.ini b/rdkb_debug_arm.ini deleted file mode 100644 index 2b5996c..0000000 --- a/rdkb_debug_arm.ini +++ /dev/null @@ -1,58 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#### Logging #### - -EnableMPELog = TRUE - -SEPARATE.LOGFILE.SUPPORT=FALSE -LOG.RDK.DEFAULT = WARNING -LOG.RDK.TR69 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PAM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PSM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MOCA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MTA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TDM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SSD = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.FU = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Misc = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SNMP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBPA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.HOTSPOT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCPSNOOP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.NOTIFY = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WECB = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WECBMASTER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.ETHAGENT = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.DHCPMGR = ALL FATAL ERROR WARNING NOTICE INFO DEBUG -LOG.RDK.GWPROV = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.PARODUS = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.AKER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RTMESSAGE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.GWPROVETHWAN = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.LIBSYSCALLWRAPPER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SPDTST = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.T2 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBCONFIG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.ADVSEC = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XDNS = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CPUPROCANALYZER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.IMAGEHEALTHCHECKER = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBCONFIGRFC = ALL FATAL ERROR WARNING NOTICE INFO DEBUG TRACE diff --git a/rdkb_debug_atom.ini b/rdkb_debug_atom.ini deleted file mode 100644 index 66f72a7..0000000 --- a/rdkb_debug_atom.ini +++ /dev/null @@ -1,43 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#### Logging #### - -EnableMPELog = TRUE - -SEPARATE.LOGFILE.SUPPORT=FALSE -LOG.RDK.DEFAULT = WARNING -LOG.RDK.CR = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WIFI = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMRXM = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMBRG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMRBP = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.CSCWFMMON = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Harvester = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.XSMART = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.TOUCHSTONE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MESH = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.MeshService = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBPA = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.Seshat = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.SPDTST = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.BLE = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.T2 = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.WEBCONFIG = FATAL ERROR WARNING NOTICE INFO -LOG.RDK.RTMESSAGE = FATAL ERROR WARNING NOTICE INFO - diff --git a/rdkb_log4crc b/rdkb_log4crc deleted file mode 100644 index cd7c6f6..0000000 --- a/rdkb_log4crc +++ /dev/null @@ -1,517 +0,0 @@ - - - - - - - - - - 0 - - 0 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rdkb_log4crc_arm b/rdkb_log4crc_arm deleted file mode 100644 index 61ae7aa..0000000 --- a/rdkb_log4crc_arm +++ /dev/null @@ -1,312 +0,0 @@ - - - - - - - - - - 0 - - 0 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rdkb_log4crc_atom b/rdkb_log4crc_atom deleted file mode 100644 index 1b62d0a..0000000 --- a/rdkb_log4crc_atom +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - - - - 0 - - 0 - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/rdkc_log4crc b/rdkc_log4crc deleted file mode 100644 index ccdba99..0000000 --- a/rdkc_log4crc +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - - - 0 - - 0 - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/include/rdk_debug_priv.h b/src/include/rdk_debug_priv.h index aed40b0..b2b71c4 100644 --- a/src/include/rdk_debug_priv.h +++ b/src/include/rdk_debug_priv.h @@ -29,50 +29,17 @@ extern "C" { #endif -/** Maximum limit on the number of Modules logged*/ +void rdk_dbg_priv_init(void); +void rdk_dbg_priv_config(void); +void rdk_dbg_priv_deinit(void); +void rdk_dbg_priv_ext_init(const char* logdir, const char* log_file_name, long maxCount, long maxSize); +void rdk_dbg_priv_shutdown(); -#define RDK_MAX_MOD_COUNT 512 +void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args); +void rdk_dbg_priv_reconfig(const char *pModuleName, const char *pLogLevel); -/** This variable is described in rdk_dbg_priv_log.c - to be used by - * rdk_debug_priv_.* files only. - */ -extern uint32_t rdk_g_logControlTbl[]; -extern rdk_logger_Bool dbg_logViaUDP; - -/** - * The rdk_logger_envGet() function will get the value of the specified - * environment variable. - * - * @param name is a pointer to the name of the target environment variable. - * - * @return a pointer to the associated string value of the target environment - * variable or NULL if the variable can't be found. - */ -const char* rdk_logger_envGet(const char *name); - -/** - * The rdk_logger_env_add_conf_file() function sets up the environment variable - * storage by parsing configuration file. - * - * @param path Path of the file. - * @return Returns relevant RDK_OSAL error code on failure, otherwise RDK_SUCCESS - * is returned. - */ -rdk_Error rdk_logger_env_add_conf_file(const char * path); -rdk_Error rdk_logger_env_rem_conf_details(void); - -void rdk_dbg_priv_LogControlInit(void); -void rdk_dbg_priv_Init(void); -void rdk_dbg_priv_DeInit(void); -void rdk_dbg_priv_Shutdown(); -const char * rdk_dbg_priv_LogControlOpSysIntf(char *logName, char *cfgStr); -const char * rdk_dbg_priv_LogQueryOpSysIntf(char *modName, char *cfgStr, int cfgStrMaxLen); -void rdk_debug_priv_log_msg( rdk_LogLevel level, - int module, const char *module_name, const char* format, va_list args); -void RDK_LOG_ControlCB(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status); -void rdk_dbgDumpLog(const char* path); -void rdk_dbgInit(); -void rdk_dbgDeinit(); +void rdk_dbg_init(); +void rdk_dbg_deinit(); #ifdef __cplusplus } diff --git a/src/include/rdk_dynamic_logger.h b/src/include/rdk_dynamic_logger.h index 9c8f13f..e087e0a 100644 --- a/src/include/rdk_dynamic_logger.h +++ b/src/include/rdk_dynamic_logger.h @@ -22,11 +22,7 @@ #include -void rdk_dyn_log_processPendingRequest(void); - void rdk_dyn_log_init(void); - -void rdk_dyn_log_deInit(void); - -char* rdk_loglevelToString(unsigned char log_level, rdk_LogLevel isLogEnabled); +void rdk_dyn_log_deinit(void); +void rdk_dyn_log_process_pending_request(void); #endif /* _RDK_DBG_PRIV_DYNLOG_H */ diff --git a/include/rdk_utils.h b/src/include/rdk_utils.h similarity index 88% rename from include/rdk_utils.h rename to src/include/rdk_utils.h index 9d228d4..ee19f25 100644 --- a/include/rdk_utils.h +++ b/src/include/rdk_utils.h @@ -36,7 +36,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -55,8 +54,11 @@ const char* rdk_logger_envGetValueFromNum(int number); const char* rdk_logger_envGetModFromNum(int Num); -rdk_Error rdk_logger_env_add_conf_file(const char * path); +rdk_Error rdk_logger_parse_config(const char * path); +rdk_Error rdk_logger_release_config(void); + +char* rdk_loglevelToString(rdk_LogLevel level, rdk_logger_Bool isLogEnabled); /** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API #ifdef __cplusplus diff --git a/src/rdk_debug.c b/src/rdk_debug.c index 6f8b01f..a78d0b0 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -37,78 +37,23 @@ #include #include -extern int global_count; - -/** - * @brief Touch the file which can be used to check whether to log or not. - * - * @param[in] pszFile Character string representing name of the file to be created. - * @return None. - */ -static void TouchFile(const char * pszFile) -{ - if(NULL != pszFile) - { - FILE * fp = fopen(pszFile, "w"); - if(NULL != fp) - { - fclose(fp); - } - } -} - -/** - * @brief Dump the debug log. It will Dump all the current settings so that an analysis of a log - * file will include what logging information to expect. - * - * @param[in] path Character string representing path of the temp file to be created. - * @return None. - */ -void rdk_dbgDumpLog(const char* path) -{ - int mod, i; - char config[128]; - const char *modptr = NULL; - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", "\n"); - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", - "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"); - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", "Stack level logging levels: \n"); - - /** - * Now just dump all the current settings so that an analysis of a log - * file will include what logging information to expect - */ - for (mod = 1; mod <= global_count; mod++) - { - modptr = rdk_logger_envGetModFromNum(mod); - - memset(config, 0, sizeof(config)); - (void) rdk_dbg_priv_LogQueryOpSysIntf((char*) modptr, config, 127); - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", - "Initial Logging Level for %-10s: %s\n", modptr, config); - } - - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.OS", - "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n\n"); - TouchFile(path); -} - /** * @brief Initialize the underlying MPEOS debug support. This API must be called only once per boot cycle. * @return None. */ static rdk_logger_Bool inited = FALSE; -void rdk_dbgInit() +void rdk_dbg_init() { if (!inited) { - rdk_dbg_priv_Init(); + rdk_dbg_priv_init(); inited = TRUE; + rdk_dbg_priv_config(); } } -void rdk_dbgDeinit() +void rdk_dbg_deinit() { if (inited) { @@ -124,41 +69,40 @@ void rdk_dbgDeinit() * @param[in] module The name of the module for which this message belongs to, it is mentioned in debug.ini. * @param[in] format Printf style string containing the log message. */ -void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, - const char *format, ...) +void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...) { -#if !defined(RDK_LOG_DISABLE) int num; va_list args; va_start(args, format); - /** Get the registered value of module */ - num = rdk_logger_envGetNum(module); - if(num < 0) - { - va_end(args); - return; - } - rdk_debug_priv_log_msg( level, num, module, - format, args); + rdk_dbg_priv_log_msg(level, module, format, args); va_end(args); -#endif /* RDK_LOG_DISABLE */ } -void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, - const char *format, va_list args) +void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args) { -#if !defined(RDK_LOG_DISABLE) - int num; + rdk_dbg_priv_log_msg(level, module, format, args); +} - /** Get the registered value of module */ - num = rdk_logger_envGetNum(module); - if(num < 0) - { - return; - } - rdk_debug_priv_log_msg( level, num, module, - format, args); -#endif /* RDK_LOG_DISABLE */ +/** + * @brief Function to sets a specific log level of a module. + * + * @param[in] module The module name or category for for which the log level shall be checked + * @param[in] level The debug logging level. + * + * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. + */ +rdk_logger_Bool rdk_logger_enable_logLevel(const char *pModuleName, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl) +{ + if (!pModuleName) + return FALSE; + + const char* logLevelName = rdk_loglevelToString(logLevel, enableLogLvl); + + if (!logLevelName) + return FALSE; + + rdk_dbg_priv_reconfig (pModuleName, logLevelName); + return TRUE; } diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index 3456cb0..0e6ba8a 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -54,6 +54,9 @@ #include "rdk_dynamic_logger.h" #include "log4c.h" #include +#include +#include +#include #ifdef SYSTEMD_JOURNAL #include @@ -64,32 +67,36 @@ #include "syslog_helper_ifc.h" #endif -/// Debugging messages are enabled. Default is enabled (1) and 0 for off. -static int g_debugEnabled = 1; - +log4c_category_t* gRootCat = NULL; +int gRootPriority = 0; extern int global_count; +static int rdk_logLevel_to_log4c_priority(int level) { + switch (level) { + case 0: return LOG4C_PRIORITY_FATAL; // 000 + case 1: return LOG4C_PRIORITY_ERROR; // 300 + case 2: return LOG4C_PRIORITY_WARN; // 400 + case 3: return LOG4C_PRIORITY_NOTICE; // 500 + case 4: return LOG4C_PRIORITY_INFO; // 600 + case 5: return LOG4C_PRIORITY_DEBUG; // 700 + case 6: return LOG4C_PRIORITY_TRACE; // 800 + default: return LOG4C_PRIORITY_UNKNOWN; + } + } + +#define LOG4C_PRIORITY_NONE -1 + /** * Returns 1 if logging has been requested for the corresponding module (mod) * and level (lvl) combination. To be used in rdk_dbg_priv_* files ONLY. */ -#define WANT_LOG(mod, lvl) ( ( ((mod) >= 0) && ((mod) < RDK_MAX_MOD_COUNT) ) ? (rdk_g_logControlTbl[(mod)] & (1 << (lvl))) : 0 ) - +#define IS_LOGGING_ENABLED_FOR_LEVEL(module_name, level) \ + (log4c_category_get(module_name) && \ + (rdk_logLevel_to_log4c_priority(level) <= log4c_category_get_priority(log4c_category_get(module_name)))) /** Skip whitespace in a c-style string. */ #define SKIPWHITE(cptr) while ((*cptr != '\0') && isspace(*cptr)) cptr++ -/** Bit mask for trace TRACE logging level. */ -#define LOG_TRACE ( (1 << RDK_LOG_TRACE) ) - -/** Turns on FATAL, ERROR, WARN NOTICE & INFO. */ -#define LOG_ALL ( (1 << RDK_LOG_FATAL) | (1 << RDK_LOG_ERROR) | \ - (1 << RDK_LOG_WARN) | (1 << RDK_LOG_INFO) | \ - (1 << RDK_LOG_NOTICE)) - -/** All logging 'off'. */ -#define LOG_NONE 0 - #define HOSTADDR_STR_MAX 255 @@ -113,28 +120,6 @@ static int stream_env_close(log4c_appender_t * appender); static rdk_logger_Bool g_initialized = FALSE; - -/** Global variable used to control logging. */ -uint32_t rdk_g_logControlTbl[RDK_MAX_MOD_COUNT]; - -/** UDP logging variables. */ -rdk_logger_Bool dbg_logViaUDP = FALSE; -int dbg_udpSocket; -struct sockaddr_in dbg_logHostAddr; - -log4c_category_t* stackCat = NULL; - -enum -{ - /** Used as an array index. */ - ERR_INVALID_MOD_NAME = 0, ERR_INVALID_LOG_NAME -}; - -enum -{ - RC_ERROR, RC_OK -}; - static const char *errorMsgs[] = { "Error: Invalid module name.", "Warning: Ignoring invalid log name(s)." }; @@ -142,9 +127,6 @@ static const char *errorMsgs[] = /** * Initialize Debug API. */ -static log4c_category_t* defaultCategory = NULL; -static log4c_category_t* glibCategory = NULL; - static const log4c_layout_type_t log4c_layout_type_dated_nocr = { "dated_nocr", dated_format_nocr, }; @@ -171,30 +153,62 @@ static const log4c_appender_type_t log4c_appender_type_stream_env_append_plus_st { "stream_env_append_plus_stdout", stream_env_append_open, stream_env_plus_stdout_append, stream_env_close, }; -void rdk_dbg_priv_Init() +void rdk_dbg_priv_init() { const char* envVar; - if (initLogger("RI")) + if (initLogger("LOG.RDK")) { fprintf(stderr, "%s -- initLogger failure?!\n", __FUNCTION__); } - stackCat = log4c_category_get("RI.Stack"); + gRootCat = log4c_category_get("LOG.RDK"); +} + +void rdk_dbg_priv_ext_init(const char* logdir, const char* log_file_name, long maxCount, long maxSize) +{ + char fullpath[512]; + snprintf(fullpath, sizeof(fullpath), "%s/%s", logdir, log_file_name); - rdk_dbg_priv_LogControlInit(); + const char* cat_name = "LOG.RDK"; + log4c_category_t* cat = log4c_category_get(cat_name); + if (!cat) { + cat = log4c_category_new(cat_name); + } - /* Try to get logging option. */ - envVar = rdk_logger_envGet("EnableMPELog"); - if (NULL != envVar) - { - g_debugEnabled = (strcasecmp(envVar, "TRUE") == 0); + log4c_appender_t* app = log4c_appender_get(fullpath); + if (!app) { + app = log4c_appender_new(fullpath); } + log4c_appender_set_type(app, log4c_appender_type_get("rollingfile")); + + rollingfile_udata_t *rudata = rollingfile_make_udata(); + rollingfile_udata_set_logdir(rudata, logdir); + rollingfile_udata_set_files_prefix(rudata, log_file_name); + + log4c_rollingpolicy_t *policy = log4c_rollingpolicy_get(cat_name); + if (!policy) { + policy = log4c_rollingpolicy_new(cat_name); + } + log4c_rollingpolicy_set_type(policy, log4c_rollingpolicy_type_get("sizewin")); + + rollingpolicy_sizewin_udata_t *sizewin_udata = sizewin_make_udata(); + sizewin_udata_set_file_maxsize(sizewin_udata, maxSize); + sizewin_udata_set_max_num_files(sizewin_udata, maxCount); + log4c_rollingpolicy_set_udata(policy, sizewin_udata); + + rollingfile_udata_set_policy(rudata, policy); + log4c_appender_set_udata(app, rudata); + + log4c_layout_t* layout = log4c_layout_get("comcast_dated"); + log4c_appender_set_layout(app, layout); + + log4c_category_set_appender(cat, app); } -void rdk_dbg_priv_DeInit() +void rdk_dbg_priv_deinit() { - stackCat = NULL; + gRootCat = NULL; } /** @@ -214,6 +228,21 @@ static void forceUpperCase(char *token) } } +/** + * String names that correspond to the various logging types. + * Note: This array *must* match the RDK_LOG_* enum. + */ +const char *rdk_logLevelStrings[RDK_LOG_NONE] = +{ + "FATAL", + "ERROR", + "WARNING", + "NOTICE", + "INFO", + "DEBUG", + "TRACE", +}; + /** * Convert a log level name to the correspodning log level enum value. * @@ -223,7 +252,7 @@ static void forceUpperCase(char *token) static int logNameToEnum(const char *name) { int i = 0; - while (i < ENUM_RDK_LOG_COUNT) + while (i < RDK_LOG_NONE) { if (strcmp(name, rdk_logLevelStrings[i]) == 0) { @@ -256,101 +285,6 @@ static void extractToken(const char **srcStr, char *tokBuf) *srcStr = src; } -/** - * Parse a whitespace delimited list of log types and log type meta names. - * - * @param cfgStr String containing one more log types. (Right hand - * side of INI file entry.) - * - * @param defConfig Default configuration to base the return value on. - * - * @return Returns a bit mask that can be used as an entry in - * #rdk_g_logControlTbl. - */ -static int parseLogConfig(const char *cfgStr, uint32_t *configEntry, - const char **msg) -{ - uint32_t config = *configEntry; - char logTypeName[128] = - { 0 }; - int rc = RC_OK; - - *msg = ""; - - SKIPWHITE(cfgStr) - ; - if (*cfgStr == '\0') - { - *msg = "Warning: Empty log level confguration."; - return RC_ERROR; - } - - while (*cfgStr != '\0') - { - /* Extract and normalise log type name token. */ - - memset(logTypeName, 0, sizeof(logTypeName)); - extractToken(&cfgStr, logTypeName); - forceUpperCase(logTypeName); - - /* Handle special meta names. */ - - if (strcmp(logTypeName, "ALL") == 0) - { - config |= LOG_ALL; - } - else if (strcmp(logTypeName, "NONE") == 0) - { - config = LOG_NONE; - } - else if (strcmp(logTypeName, "TRACE") == 0) - { - config |= LOG_TRACE; - } - else if (strcmp(logTypeName, "!TRACE") == 0) - { - config &= ~LOG_TRACE; - } - else - { - /* Determine the corresponding bit for the log name. */ - int invert = 0; - const char *name = logTypeName; - int logLevel = -1; - - if (logTypeName[0] == '!') - { - invert = 1; - name = &logTypeName[1]; - } - - logLevel = logNameToEnum(name); - if (logLevel != -1) - { - if (invert) - { - config &= ~(1 << logLevel); - } - else - { - config |= (1 << logLevel); - } - } - else - { - *msg = errorMsgs[ERR_INVALID_LOG_NAME]; - rc = RC_ERROR; - } - } - - SKIPWHITE(cfgStr) - ; - } - - *configEntry = config; - return rc; -} - static void printTime(const struct tm *pTm, char *pBuff) { sprintf(pBuff,"%02d%02d%02d-%02d:%02d:%02d",pTm->tm_year + 1900 - 2000, pTm->tm_mon + 1, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec); @@ -361,138 +295,91 @@ static void printTime(const struct tm *pTm, char *pBuff) * EXPORTED FUNCTIONS * ****************************************************************************/ - -/** - * Initialize the debug log control table. This should be called from - * the initialization routine of the debug manager. - */ -void rdk_dbg_priv_LogControlInit(void) +void rdk_dbg_priv_config(void) { - char envVarName[128] = - { 0 }; - const char *envVarValue = NULL; - uint32_t defaultConfig = 0; - int mod = 0; - const char *msg = ""; - - /** Pre-condition the control table to disable all logging. This - * means that if no logging control statements are present in the - * debug.ini file all logging will be suppressed. */ - memset(rdk_g_logControlTbl, 0, sizeof(rdk_g_logControlTbl)); - - /** Intialize to the default configuration for all modules. */ - strncpy(envVarName,"LOG.RDK.DEFAULT",sizeof(envVarName)); - envVarValue = rdk_logger_envGet(envVarName); - if ((envVarValue != NULL) && (envVarValue[0] != 0)) + const char *defaultValue = rdk_logger_envGet("LOG.RDK.DEFAULT"); + if (defaultValue && defaultValue[0] != 0) { - (void) parseLogConfig(envVarValue, &defaultConfig, &msg); - for (mod = 1; mod <= global_count; mod++) + char levelName[32]; + strncpy(levelName, defaultValue, sizeof(levelName)-1); + levelName[sizeof(levelName)-1] = '\0'; + forceUpperCase(levelName); + + if (!gRootCat) + gRootCat = log4c_category_get("LOG.RDK"); + + if (!gRootCat) { - rdk_g_logControlTbl[mod] = defaultConfig; + printf("LOG.RDK.DEFAULT is not defined..\n"); + return; } - } - /** Configure each module from the ini file. Note: It is not an - * error to have no entry in the ini file for a module - we simply - * leave it at the default logging. */ - for (mod = 1; mod <= global_count; mod++) - { - /** Get the logging level */ - envVarValue = rdk_logger_envGetValueFromNum(mod); - if ((envVarValue != NULL) && (envVarValue[0] != '\0')) + if (strcasecmp(levelName, "NONE") == 0) { - (void) parseLogConfig(envVarValue, &rdk_g_logControlTbl[mod], - &msg); + log4c_category_set_priority(gRootCat, LOG4C_PRIORITY_NONE); } - } -} - -/** - * @brief Function to check if a specific log level of a module is enabled. - * - * @param[in] module The module name or category for for which the log level shall be checked (as mentioned in debug.ini). - * @param[in] level The debug logging level. - * - * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. - */ -rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level) -{ - int number = rdk_logger_envGetNum(module); - if (WANT_LOG(number, level)) - { - return TRUE; - } - else - { - return FALSE; - } -} - -/** - * Modify the debug log control table. - */ -void rdk_dbg_priv_SetLogLevelString(const char* pszModuleName, const char* pszLogLevels) -{ - const char *envVarName; - uint32_t defaultConfig = 0; - int mod = 0; - const char *msg = ""; - - if ((pszModuleName != NULL) && (pszLogLevels != NULL)) - { - /* Intialize to the default configuration for all modules. */ - if(0 == strcmp(pszModuleName, "LOG.RDK.DEFAULT")) + else { - (void) parseLogConfig(pszLogLevels, &defaultConfig, &msg); - for (mod = 1; mod <= global_count; mod++) + int lvl = logNameToEnum(levelName); + if (lvl >= 0 && lvl < RDK_LOG_NONE) { - rdk_g_logControlTbl[mod] = defaultConfig; + log4c_category_set_priority(gRootCat, rdk_logLevel_to_log4c_priority(lvl)); } - printf("rdk_dbg_priv_SetLogLevelString: Set Logging Level for '%s' to '%s'\n", pszModuleName, pszLogLevels); - return; } + gRootPriority = log4c_category_get_priority(gRootCat); + } + else + { + printf("LOG.RDK.DEFAULT is not defined..\n"); + return; + } - /* Configure each module from the ini file. Note: It is not an - * error to have no entry in the ini file for a module - we simply - * leave it at the default logging. */ - for (mod = 1; mod <= global_count; mod++) + for (int mod = 1; mod <= global_count; mod++) + { + const char* modName = rdk_logger_envGetModFromNum(mod); + const char* modValue = rdk_logger_envGetValueFromNum(mod); + if (modName && modValue && modValue[0] != '\0') { - envVarName = rdk_logger_envGetModFromNum(mod); - if(0 == strcmp(pszModuleName, envVarName)) + char levelName[32]; + strncpy(levelName, modValue, sizeof(levelName)-1); + levelName[sizeof(levelName)-1] = '\0'; + forceUpperCase(levelName); + + log4c_category_t* cat = log4c_category_get(modName); + if (cat) { - if ((pszLogLevels != NULL) && (pszLogLevels[0] != '\0')) + if (strcasecmp(levelName, "NONE") == 0) + { + log4c_category_set_priority(cat, LOG4C_PRIORITY_NONE); + } + else { - (void) parseLogConfig(pszLogLevels, &rdk_g_logControlTbl[mod], &msg); - //printf("rdk_dbg_priv_SetLogLevelString: Set Logging Level for '%s' to '%s'\n", pszModuleName, pszLogLevels); - return; + int lvl = logNameToEnum(levelName); + if (lvl >= 0 && lvl < RDK_LOG_NONE) + { + log4c_category_set_priority(cat, rdk_logLevel_to_log4c_priority(lvl)); + } + else + { + log4c_category_set_priority(cat, LOG4C_PRIORITY_NONE); + } } } } } - printf("rdk_dbg_priv_SetLogLevelString: Failed to set Logging Level for '%s' to '%s'\n", pszModuleName, pszLogLevels); } /** - * @brief Function to sets a specific log level of a module. + * @brief Function to check if a specific log level of a module is enabled. * * @param[in] module The module name or category for for which the log level shall be checked (as mentioned in debug.ini). * @param[in] level The debug logging level. * * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. */ -rdk_logger_Bool rdk_logger_enable_logLevel(const char *moduleName, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl) +rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level) { - const char* logLevelName = rdk_loglevelToString(logLevel, enableLogLvl); - - if ((NULL == moduleName) || (NULL == logLevelName)) - { - return FALSE; - } - - rdk_dbg_priv_SetLogLevelString(moduleName, logLevelName); - - int number = rdk_logger_envGetNum(moduleName); - if (WANT_LOG(number, logLevel)) + if(IS_LOGGING_ENABLED_FOR_LEVEL(module, level)) { return TRUE; } @@ -500,162 +387,110 @@ rdk_logger_Bool rdk_logger_enable_logLevel(const char *moduleName, rdk_LogLevel { return FALSE; } - -} - -/** - * Provides an interface to query the configuration of logging in a - * specific module as a user readable string. Note: the mimimum - * acceptable length of the supplied configuration buffer is 32 bytes. - * - * @param modName Name of the module. - * - * @param cfgStr The configuration strng: which should be space - * separated module names. - * - * @param cfgStrMaxLen The maximum length of the configuration string - * to be returned including the NUL character. - * - * @return A string containing a user readable error message if an - * error occured; or "OK" upon success. - */ -const char * rdk_dbg_priv_LogQueryOpSysIntf(char *modName, char *cfgStr, - int cfgStrMaxLen) -{ - char *name = modName; - int mod = -1; - uint32_t modCfg = 0; - int level = -1; - - assert(modName); - assert(cfgStr); - assert(cfgStrMaxLen > 32); - - cfgStrMaxLen -= 1; /**< Ensure there is space for NUL. */ - strncpy(cfgStr,"",cfgStrMaxLen); - - /** Get the module configuration. Note: DEFAULT is not valid as it - * is an alias. - */ - forceUpperCase(name); - mod = rdk_logger_envGetNum(modName); - if (mod < 0) - { - return "Unknown module specified."; - } - modCfg = rdk_g_logControlTbl[mod]; - - /** Try and find a succinct way of describing the configuration. */ - - if (modCfg == 0) - { - strncpy(cfgStr,"NONE",cfgStrMaxLen); - return "OK"; /* This is a canonical response. */ - } - - /** Loop through the control word and print out the enabled levels. */ - - for (level = 0; level < ENUM_RDK_LOG_COUNT; level++) - { - if (modCfg & (1 << level)) - { - /** Stop building out the config string if it would exceed - * the buffer length. - */ - if (strlen(cfgStr) + strlen(rdk_logLevelStrings[level]+1) - > (size_t) cfgStrMaxLen) - { - return "Warning: Config string too long, config concatenated."; - } - - strncat(cfgStr," ",cfgStrMaxLen); /* Not efficient - rah rah. */ - strncat(cfgStr,rdk_logLevelStrings[level],cfgStrMaxLen); - } - } - - return "OK"; } -void rdk_debug_priv_log_msg( rdk_LogLevel level, - int module, const char *module_name, const char* format, va_list args) +void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args) { /** Get the category from module name */ - static log4c_category_t *cat_cache[RDK_MAX_MOD_COUNT] = {NULL}; char cat_name[64] = {'\0'}; log4c_category_t* cat = NULL; + int prio = 0; /* Handling process request here. This is not a blocking call and it shall return immediately */ - rdk_dyn_log_processPendingRequest(); + rdk_dyn_log_process_pending_request(); - if (!g_debugEnabled || !WANT_LOG(module, level)) + cat = log4c_category_get(module_name); + prio = log4c_category_get_priority(cat); + if (cat && prio == LOG4C_PRIORITY_NOTSET && gRootCat) { + log4c_category_set_priority(cat, gRootPriority); + prio = gRootPriority; + } + + if(!cat) { - return; + cat = gRootCat; } - char *parent_cat_name = (char *)log4c_category_get_name(stackCat); - snprintf(cat_name, sizeof(cat_name)-1, "%s.%s", parent_cat_name == NULL ? "" : parent_cat_name, module_name); - - if((module >= 0) && (module < RDK_MAX_MOD_COUNT)) + if(!cat) { - if (cat_cache[module] == NULL) { - /** Only doing a read here, lock not needed */ - cat_cache[module] = log4c_category_get(cat_name); - } - - cat = cat_cache[module]; + return; } - /* CID :19939-- some function when explicitly call this function, it might have module < 0, then the else condition will be applicable*/ - else + + if (!IS_LOGGING_ENABLED_FOR_LEVEL(module_name, level)) { - cat = log4c_category_get(cat_name); + return; } switch (level) { - case RDK_LOG_FATAL: - log4c_category_vlog(cat, LOG4C_PRIORITY_FATAL, format, args); - break; - case RDK_LOG_ERROR: - log4c_category_vlog(cat, LOG4C_PRIORITY_ERROR, format, args); - break; - case RDK_LOG_WARN: - log4c_category_vlog(cat, LOG4C_PRIORITY_WARN, format, args); - break; - case RDK_LOG_NOTICE: - log4c_category_vlog(cat, LOG4C_PRIORITY_NOTICE, format, args); - break; - case RDK_LOG_INFO: - log4c_category_vlog(cat, LOG4C_PRIORITY_INFO, format, args); - break; - case RDK_LOG_DEBUG: - log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); - break; - case RDK_LOG_TRACE: - log4c_category_vlog(cat, LOG4C_PRIORITY_TRACE, format, args); - break; - default: - log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); - break; + case RDK_LOG_FATAL: + log4c_category_vlog(cat, LOG4C_PRIORITY_FATAL, format, args); + break; + case RDK_LOG_ERROR: + log4c_category_vlog(cat, LOG4C_PRIORITY_ERROR, format, args); + break; + case RDK_LOG_WARN: + log4c_category_vlog(cat, LOG4C_PRIORITY_WARN, format, args); + break; + case RDK_LOG_NOTICE: + log4c_category_vlog(cat, LOG4C_PRIORITY_NOTICE, format, args); + break; + case RDK_LOG_INFO: + log4c_category_vlog(cat, LOG4C_PRIORITY_INFO, format, args); + break; + case RDK_LOG_DEBUG: + log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); + break; + case RDK_LOG_TRACE: + log4c_category_vlog(cat, LOG4C_PRIORITY_TRACE, format, args); + break; + default: + log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); + break; } } -void RDK_LOG_ControlCB(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) +void rdk_dbg_priv_reconfig(const char *pModuleName, const char *pLogLevel) { char logTypeName[20] = {'\0'}; - if ((NULL == moduleName) || (NULL == loggingLevel)) + if ((NULL == pModuleName) || (NULL == pLogLevel)) { return; } - strncpy(logTypeName, loggingLevel, sizeof(logTypeName)-1); + strncpy(logTypeName, pLogLevel, sizeof(logTypeName)-1); if (logTypeName[0] == '~') { logTypeName[0] = '!'; } - rdk_dbg_priv_SetLogLevelString(moduleName, (const char *)logTypeName); + int disable = 0; + if (logTypeName[0] == '!') { + disable = 1; + memmove(logTypeName, logTypeName + 1, strlen(logTypeName)); + } + + int prio = LOG4C_PRIORITY_INFO; // default + if (strcasecmp(logTypeName, "FATAL") == 0) prio = LOG4C_PRIORITY_FATAL; + else if (strcasecmp(logTypeName, "ERROR") == 0) prio = LOG4C_PRIORITY_ERROR; + else if (strcasecmp(logTypeName, "WARNING") == 0) prio = LOG4C_PRIORITY_WARN; + else if (strcasecmp(logTypeName, "NOTICE") == 0) prio = LOG4C_PRIORITY_NOTICE; + else if (strcasecmp(logTypeName, "INFO") == 0) prio = LOG4C_PRIORITY_INFO; + else if (strcasecmp(logTypeName, "DEBUG") == 0) prio = LOG4C_PRIORITY_DEBUG; + else if (strcasecmp(logTypeName, "TRACE") == 0) prio = LOG4C_PRIORITY_TRACE; + else if (strcasecmp(logTypeName, "NONE") == 0) prio = LOG4C_PRIORITY_NONE; + + log4c_category_t* cat = log4c_category_get(pModuleName); + if (cat) { + if (disable) { + log4c_category_set_priority(cat, gRootPriority); + } + else { + log4c_category_set_priority(cat, prio); + } + } } @@ -685,11 +520,6 @@ static int initLogger(char *category) fprintf(stderr, "log4c_init() failed?!"); return -1; } - else - { - defaultCategory = log4c_category_get(category); - glibCategory = log4c_category_get("RI.GLib"); - } return 0; } @@ -1008,6 +838,3 @@ static int stream_env_close(log4c_appender_t* appender) return fclose(fp); } - -/*************************End Copied from ri_log.c******************/ - diff --git a/src/rdk_dynamic_logger.c b/src/rdk_dynamic_logger.c index e768659..c30f5f7 100644 --- a/src/rdk_dynamic_logger.c +++ b/src/rdk_dynamic_logger.c @@ -63,12 +63,14 @@ static char * rdk_dyn_log_logLevelToString(unsigned char log_level) return (negate) ? "!DEBUG":"DEBUG"; case RDK_LOG_TRACE: return (negate) ? "!TRACE":"TRACE"; + case RDK_LOG_NONE: + return "NONE"; } return NULL; } -static void rdk_dyn_log_validateComponentName(const unsigned char *buf) +static void rdk_dyn_log_validate_component_name(const unsigned char *buf) { unsigned char log_level = 0; int app_len, comp_len, i = DL_SIGNATURE_LEN; @@ -92,12 +94,12 @@ static void rdk_dyn_log_validateComponentName(const unsigned char *buf) loggingLevel = rdk_dyn_log_logLevelToString(log_level); if(NULL != loggingLevel) { memcpy(comp_name,buf+(++i),comp_len); - RDK_LOG_ControlCB(comp_name, NULL, loggingLevel, 0); + rdk_dbg_priv_reconfig(comp_name, loggingLevel); fprintf(stderr,"%s(): Set %s loglevel for the component %s of the process %s\n",__func__,loggingLevel,comp_name,__progname); } } -void rdk_dyn_log_processPendingRequest() +void rdk_dyn_log_process_pending_request() { char buf[128] = {0}; struct sockaddr_in sender_addr; @@ -107,7 +109,6 @@ void rdk_dyn_log_processPendingRequest() if(-1 == g_dl_socket) return; - memset(&sender_addr,0,sizeof(sender_addr)); while(1) { FD_ZERO(&rfds); @@ -140,7 +141,7 @@ void rdk_dyn_log_processPendingRequest() */ if((0 == strcmp("127.0.0.1",inet_ntoa(sender_addr.sin_addr))) && (numbytes == buf[4]+DL_SIGNATURE_LEN+1)) { - rdk_dyn_log_validateComponentName(buf); + rdk_dyn_log_validate_component_name(buf); } } } @@ -177,30 +178,9 @@ void rdk_dyn_log_init() fprintf(stderr, "%sg_dl_socket = %d __progname = %s \n",__func__,g_dl_socket,__progname); } -void rdk_dyn_log_deInit() +void rdk_dyn_log_deinit() { close(g_dl_socket); g_dl_socket = -1; } -char* rdk_loglevelToString(unsigned char log_level, rdk_LogLevel isLogEnabled) -{ - switch(log_level){ - case RDK_LOG_FATAL: - return (isLogEnabled) ? "FATAL":"!FATAL"; - case RDK_LOG_ERROR: - return (isLogEnabled) ? "ERROR":"!ERROR"; - case RDK_LOG_WARN: - return (isLogEnabled) ? "WARNING":"!WARNING"; - case RDK_LOG_NOTICE: - return (isLogEnabled) ? "NOTICE":"!NOTICE"; - case RDK_LOG_INFO: - return (isLogEnabled) ? "INFO":"!INFO"; - case RDK_LOG_DEBUG: - return (isLogEnabled) ? "DEBUG":"!DEBUG"; - case RDK_LOG_TRACE: - return (isLogEnabled) ? "TRACE":"!TRACE"; - } - - return NULL; -} diff --git a/src/rdk_logger_init.c b/src/rdk_logger_init.c index ceff225..8ad825d 100644 --- a/src/rdk_logger_init.c +++ b/src/rdk_logger_init.c @@ -67,28 +67,19 @@ rdk_Error rdk_logger_init(const char* debugConfigFile) debugConfigFile = DEBUG_CONF_FILE; } - ret = rdk_logger_env_add_conf_file(debugConfigFile); + /* Read the config file & populate pre-configured log levels */ + ret = rdk_logger_parse_config(debugConfigFile); if ( RDK_SUCCESS != ret) { printf("%s:%d Adding debug config file %s failed\n", __FUNCTION__, __LINE__, debugConfigFile); return ret; } + /* Perform Logger Internal Init */ + rdk_dbg_init(); - rdk_dbgInit(); + /* Perform Dynamin Logger Internal Init */ rdk_dyn_log_init(); - snprintf(buf, BUF_LEN-1, "/tmp/%s", "debugConfigFile_read"); - buf[BUF_LEN-1] = '\0'; - - if((0 == stat(buf, &st) && (0 != st.st_ino))) - { - printf("%s %s Already Stack Level Logging processed... not processing again.\n", __FUNCTION__, debugConfigFile); - } - else - { - rdk_dbgDumpLog(buf); - } - /** * Requests not to send SIGPIPE on errors on stream oriented * sockets when the other end breaks the connection. The EPIPE @@ -100,6 +91,17 @@ rdk_Error rdk_logger_init(const char* debugConfigFile) return RDK_SUCCESS; } +rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config) + { + rdk_Error ret; + ret = RDK_LOGGER_INIT(); + if (ret == RDK_SUCCESS) + { + rdk_dbg_priv_ext_init(config->logdir, config->fileName, config->maxCount, config->maxSize); + } + return ret; + } + /** * @brief Cleanup the logger instantiation. * @@ -109,11 +111,8 @@ rdk_Error rdk_logger_deinit() { if(isLogInited) { - //rdk_dbgDeinit(); - rdk_dyn_log_deInit(); - //rdk_dbg_priv_DeInit(); - rdk_logger_env_rem_conf_details(); - log4c_fini(); + rdk_dyn_log_deinit(); + rdk_logger_release_config(); //isLogInited = 0; } diff --git a/src/rdk_logger_util.c b/src/rdk_logger_util.c index d25b119..b95a671 100644 --- a/src/rdk_logger_util.c +++ b/src/rdk_logger_util.c @@ -38,7 +38,7 @@ #include /*Resolve reboot and related macros.*/ -#include +#include #include #include @@ -93,7 +93,7 @@ static void trim(char *instr, char* outstr) * * @return Returns Returns RDK_SUCCESS if the setting of environment variable is successful else it returns -1. */ -rdk_Error rdk_logger_env_rem_conf_details() +rdk_Error rdk_logger_release_config() { EnvVarNode *currentNode; EnvVarNode *nextNode; @@ -122,7 +122,7 @@ rdk_Error rdk_logger_env_rem_conf_details() * @param[in] path Path of the configuration file. * @return Returns Returns RDK_SUCCESS if the setting of environment variable is successful else it returns -1. */ -rdk_Error rdk_logger_env_add_conf_file( const char * path) +rdk_Error rdk_logger_parse_config( const char * path) { const int line_buf_len = 256; @@ -174,7 +174,7 @@ rdk_Error rdk_logger_env_add_conf_file( const char * path) /* Trim all whitespace from name and value strings */ trim( name,trimname); trim( value,trimvalue); - + tmp_node = g_envCache; while(tmp_node) { @@ -182,9 +182,9 @@ rdk_Error rdk_logger_env_add_conf_file( const char * path) { break; } - tmp_node = tmp_node->next; - } - + tmp_node = tmp_node->next; + } + if(!tmp_node) { node = ( EnvVarNode*)malloc(sizeof(EnvVarNode)); @@ -198,14 +198,15 @@ rdk_Error rdk_logger_env_add_conf_file( const char * path) continue; } +#define COMP_SIGNATURE "LOG.RDK." +#define COMP_SIGNATURE_LEN 8 /** Update number only for the modules, not for environment variable */ - if ((strcmp("LOG.RDK.DEFAULT",node->name) != 0) && - (strcmp("EnableMPELog",node->name) != 0) && - (strcmp("SEPARATE.LOGFILE.SUPPORT",node->name) != 0)) + if ((strcmp("LOG.RDK.DEFAULT", node->name) != 0) && + (strncmp(COMP_SIGNATURE, node->name, COMP_SIGNATURE_LEN) == 0)) { - number++; - node->number = number; - } else + number++; + node->number = number; + } else node->number = 0; /* Insert at the front of the list */ @@ -256,11 +257,11 @@ const char* rdk_logger_envGet(const char *name) * variable or return NULL in failure condition. */ const char* rdk_logger_envGetValueFromNum(int number) -{ +{ EnvVarNode *node = g_envCache; while (node != NULL) - { + { /* Env var name match */ if (number == node->number) { @@ -329,3 +330,28 @@ const char* rdk_logger_envGetModFromNum(int Num) return NULL; } +char* rdk_loglevelToString(rdk_LogLevel log_level, rdk_logger_Bool isLogEnabled) +{ + switch(log_level){ + case RDK_LOG_FATAL: + return (isLogEnabled) ? "FATAL":"!FATAL"; + case RDK_LOG_ERROR: + return (isLogEnabled) ? "ERROR":"!ERROR"; + case RDK_LOG_WARN: + return (isLogEnabled) ? "WARNING":"!WARNING"; + case RDK_LOG_NOTICE: + return (isLogEnabled) ? "NOTICE":"!NOTICE"; + case RDK_LOG_INFO: + return (isLogEnabled) ? "INFO":"!INFO"; + case RDK_LOG_DEBUG: + return (isLogEnabled) ? "DEBUG":"!DEBUG"; + case RDK_LOG_TRACE: + return (isLogEnabled) ? "TRACE":"!TRACE"; + } + + return NULL; +} + + + +/***/ diff --git a/unittests/rdkIsDbgEnabled.cpp b/unittests/rdkIsDbgEnabled.cpp index 4033714..2ebc96b 100644 --- a/unittests/rdkIsDbgEnabled.cpp +++ b/unittests/rdkIsDbgEnabled.cpp @@ -23,9 +23,9 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include "rdk_debug.h" -#include "rdk_utils.h" #include "gtest_app.h" +#if 0 TEST(rdkIsDbgEnabled, ONLYFATAL_log_enabled) { @@ -682,4 +682,4 @@ TEST(rdkIsDbgEnabled, ALLLOGLEVELS_log_enabled) //ret = rdk_logger_deinit(); //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< Log Level of the Component to be modified\n"); - printf(" Possible values - FATAL,ERROR,WARN,NOTICE,INFO,DEBUG,TRACE\n"); + printf(" Possible values - FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE, NONE\n"); printf(" Turn off any loglevel using '~' symbol.\n"); printf(" (i.e) '~ERROR' would turn off error logs alone for that component\n"); } -static char validate_loglevel(const char* level) +static int validate_loglevel(const char* level) { char *loglevel = (char *)level; - char negate = 0; + unsigned char negate = 0; if(loglevel[0] == '~') { loglevel++; negate = 0x80; } - if(0 == strncmp(loglevel,"FATAL",5)) + if(0 == strncmp(loglevel, "FATAL", 5)) return negate|RDK_LOG_FATAL; - else if(0 == strncmp(loglevel,"ERROR",5)) + else if(0 == strncmp(loglevel, "ERROR", 5)) return negate|RDK_LOG_ERROR; - else if(0 == strncmp(loglevel,"WARN",4)) + else if(0 == strncmp(loglevel, "WARN", 4)) return negate|RDK_LOG_WARN; - else if(0 == strncmp(loglevel,"NOTICE",6)) + else if(0 == strncmp(loglevel, "NOTICE", 6)) return negate|RDK_LOG_NOTICE; - else if(0 == strncmp(loglevel,"INFO",4)) + else if(0 == strncmp(loglevel, "INFO", 4)) return negate|RDK_LOG_INFO; - else if(0 == strncmp(loglevel,"DEBUG",5)) + else if(0 == strncmp(loglevel, "DEBUG", 5)) return negate|RDK_LOG_DEBUG; - else if(0 == strncmp(loglevel,"TRACE",6)) + else if(0 == strncmp(loglevel, "TRACE", 6)) return negate|RDK_LOG_TRACE; + else if(0 == strncmp(loglevel, "NONE", 4)) + return RDK_LOG_NONE; else - return ENUM_RDK_LOG_COUNT; + return -1; } static int validate_module_name(const char *name) @@ -86,7 +88,7 @@ int main(int argc, char *argv[]) { struct sockaddr_in dest_addr; int i, sockfd, numbytes, addr_len, app_len, comp_len, optval = 1; - char level = -1; + int level = -1; unsigned char buf[128] = {0}; if (argc != 4) { @@ -95,8 +97,8 @@ int main(int argc, char *argv[]) } if(0 != strcmp("Receiver",argv[1])) { - if( (0 != strncmp(argv[2],COMP_SIGNATURE,COMP_SIGNATURE_LEN)) || - (0 != validate_module_name(argv[2])) ) { + if( (0 != strncmp(argv[2],COMP_SIGNATURE,COMP_SIGNATURE_LEN))) + { printf("Invalid module name\n"); usage(argv[0]); return -1; @@ -104,7 +106,7 @@ int main(int argc, char *argv[]) } level = validate_loglevel(argv[3]); - if(ENUM_RDK_LOG_COUNT == level) { + if(-1 == level) { printf("Invalid log level\n"); usage(argv[0]); return -1; From 0087a47dbc6c28905f7fd4424a43ed1fc8874389 Mon Sep 17 00:00:00 2001 From: Karunakaran A Date: Tue, 5 Aug 2025 23:22:40 -0400 Subject: [PATCH 07/37] Release of RDKLogger v2.0.0 Release of RDKLogger v2.0.0 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6bf1139..146a1f4 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 1.0, balaji_punnuru@cable.comcast.com,rmfwebkitifc) +AC_INIT(rdklogger, 2.0.0) AC_CONFIG_SRCDIR([src]) AM_CONFIG_HEADER(cfg/config.h) AC_CONFIG_MACRO_DIR([cfg]) From 6c05e4843ac8669931d68dd6f7b1e19502584797 Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Mon, 1 Sep 2025 21:00:01 +0530 Subject: [PATCH 08/37] RDKB-60970: RDKLogger OpenSource Migration (#20) * RDKB-60970: RDKLogger OpenSource Migration Reason for change: To fix compilation errors Test Procedure: Tested and verified Risks:Medium Priority:P1 Signed-off-by: dshett549 Signed-off-by: karunakaran_amirthalingam --- .github/workflows/L1-tests.yml | 18 +- build_dependencies.sh | 26 +++ config.mak | 58 ------ cov_build.sh | 34 ++++ doc/rdklogger-doxygen.cfg | 2 +- include/Makefile.am | 2 +- include/rdk_debug.h | 285 +------------------------- include/rdk_logger.h | 293 +++++++++++++++++++++++++++ {src/include => include}/rdk_utils.h | 0 src/Makefile.am | 2 - src/include/rdk_debug_priv.h | 2 +- src/include/rdk_dynamic_logger.h | 2 +- src/rdk_debug.c | 20 +- src/rdk_debug_priv.c | 5 +- src/rdk_logger_init.c | 2 +- src/rdk_logger_onboard.c | 2 - src/rdk_logger_util.c | 2 +- test/rdk_logger_debug_test.c | 2 +- test/rdk_logger_test_main.c | 2 +- unittests/CMakeLists.txt | 33 +-- unittests/main.cpp | 2 +- unittests/rdkIsDbgEnabled.cpp | 2 +- unittests/rdkloggerInit.cpp | 2 +- unittests/rdkloggerMsgPrintf.cpp | 2 +- unittests/rdkloggerMsgVsprintf.cpp | 2 +- utils/Makefile.am | 16 +- utils/rdk_logger_onboard_main.c | 4 +- 27 files changed, 412 insertions(+), 410 deletions(-) create mode 100755 build_dependencies.sh delete mode 100644 config.mak create mode 100755 cov_build.sh create mode 100644 include/rdk_logger.h rename {src/include => include}/rdk_utils.h (100%) diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index f8a0363..3891817 100644 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -2,15 +2,17 @@ name: l1-tests on: push: - branches: [ main, 'release/**', develop, 'topic/**' ] + branches: [ main, 'release/**', develop, 'topic/**', 'support/**' ] pull_request: - branches: [ main, 'release/**', develop, 'topic/**' ] + branches: [ main, 'release/**', develop, 'topic/**', 'support/**' ] env: WORK_DIR: ${{github.workspace}} DEP_LIB: ${{github.workspace}}/dep_lib RDKLOGGER_ROOT: ${{github.workspace}}/Rdklogger - RDKLOGGER_INSTALL_DIR: ${{github.workspace}}/Rdklogger/install + LD_LIBRARY_PATH: ${{github.workspace}}/install/lib + PKG_CONFIG_PATH: ${{github.workspace}}/install/lib/pkgconfig + RDKLOGGER_PREFIX: ${{github.workspace}}/install jobs: l1-tests: @@ -68,7 +70,7 @@ jobs: tar -xzf log4c-1.2.3.tar.gz fi cd "log4c-1.2.3" - ./configure "--prefix=${DEP_LIB}/log4c-1.2.3/install" + ./configure "--prefix=${{github.workspace}}/install" make make install @@ -83,9 +85,7 @@ jobs: autoconf export ac_cv_func_malloc_0_nonnull=yes export ac_cv_func_memset=yes - export LOG4C_CFLAGS="-I${{env.DEP_LIB}}/log4c-1.2.3/install/include/log4c/ -I${{env.DEP_LIB}}/log4c-1.2.3/src/ -I${{env.DEP_LIB}}/log4c-1.2.3/src/log4c -I${{env.DEP_LIB}}/log4c-1.2.3/install/include/" - export LOG4C_LIBS="-L${{env.DEP_LIB}}/log4c-1.2.3/install/lib" - ./configure --prefix=${{env.RDKLOGGER_INSTALL_DIR}}/lib --sysconfdir=${{env.RDKLOGGER_INSTALL_DIR}}/bin LOG4c_CFLAGS="-I${{env.DEP_LIB}}/log4c-1.2.3/src/ -I${{env.DEP_LIB}}/log4c-1.2.3/install/include/log4c/" LOG4C_LIBS="-L${{env.DEP_LIB}}/log4c-1.2.3/install/lib/liblog4c.so" + ./configure "--prefix=${{github.workspace}}/install" make make install @@ -94,7 +94,7 @@ jobs: mkdir -p ${{env.RDKLOGGER_ROOT}}/unittests UNITTESTS="${{env.RDKLOGGER_ROOT}}/unittests" cd ${UNITTESTS} - cmake -DRDKLOGGER_SOURCE_PATH=${{env.RDKLOGGER_ROOT}} -DDEP_LIB_PATH=${{env.DEP_LIB}} -DRDKLOGGER_UNITTEST_DIR=${UNITTESTS} -DCMAKE_INSTALL_PREFIX:PATH=${UNITTESTS}/build -DDEBUG_CONF_FILE="\"debug.ini\"" -S . -B build - make -C build + cmake -B build -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install/usr -DDEP_LIB_PATH=${{env.LD_LIBRARY_PATH}} -DCMAKE_VERBOSE_MAKEFILE=ON + make -C build cmake --install build ./build/rdk_logger_gtest diff --git a/build_dependencies.sh b/build_dependencies.sh new file mode 100755 index 0000000..aad865f --- /dev/null +++ b/build_dependencies.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e +set -x + +############################## +# Setup WorkSpace # +############################## +GITHUB_WORKSPACE="${PWD}" +export INSTALL_PREFIX="${PWD}/install" +export LD_LIBRARY_PATH="${PWD}/install/lib" +export PKG_CONFIG_PATH="${PWD}/install/lib/pkgconfig" +ls -la ${GITHUB_WORKSPACE} +cd ${GITHUB_WORKSPACE} + +####################################### +# Install Dependencies and packages # +####################################### +apt update && apt install -y libcurl4-openssl-dev libgtest-dev lcov gcovr libmsgpack* build-essential + +wget https://sourceforge.net/projects/log4c/files/log4c/1.2.3/log4c-1.2.3.tar.gz +tar -xzf log4c-1.2.3.tar.gz +cd "log4c-1.2.3" +./configure "--prefix=${INSTALL_PREFIX}" +make +make install + diff --git a/config.mak b/config.mak deleted file mode 100644 index 2eebe02..0000000 --- a/config.mak +++ /dev/null @@ -1,58 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#Please make sure that -# 1. PLATFORM_SDK, -# 2. RDK_DIR are exported properly before using this file - -#Path of directory containing configuration files in STB. If commented, application expects config files to be present in working directory. -#CONFIG_DIR=/config -#Configuration flags. Comment the definition for disabling and uncomment for enabling. - - -CFLAGS?= -g -Wno-format -Wunused - -ifdef CONFIG_DIR - CONFIG_PREFIX=$(CONFIG_DIR)/ -endif - - -CFLAGS += -DDEBUG_CONF_FILE="\"$(CONFIG_PREFIX)debug.ini\"" - -ARFLAGS=rcs -BUILD_DIR=$(RDK_LOGGER_DIR)/build -LIBDIR=$(BUILD_DIR)/lib - -LOGGER_INCL=$(RDK_LOGGER_DIR)/include - --include $(RDK_LOGGER_DIR)/soc/build/config.mak - -INCLUDES=-I$(LOGGER_INCL)\ - -I$(RDK_LOGGER_DIR)/../core\ - -I$(PLATFORM_SDK)/include/ \ - -I$(PLATFORM_SDK)/include/gstreamer-0.10 \ - -I$(PLATFORM_SDK)/include/glib-2.0 \ - -I$(PLATFORM_SDK)/lib/glib-2.0/include \ - -I$(PLATFORM_SDK)/usr/include/ \ - -I$(PLATFORM_SDK)/include/libxml2 \ - -I$(RDK_DIR)/opensource/include/libxml2 \ - -I$(RDK_DIR)/opensource/include/gstreamer-0.10 \ - -I$(RDK_DIR)/opensource/include/glib-2.0 \ - -I$(RDK_DIR)/opensource/include/ \ - -I$(RDK_DIR)/opensource/lib/glib-2.0/include \ - -I$(PLATFORM_SDK)/include/linux_user diff --git a/cov_build.sh b/cov_build.sh new file mode 100755 index 0000000..447a808 --- /dev/null +++ b/cov_build.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -e +set -x +############################## +# Setup WorkSpace # +############################## +GITHUB_WORKSPACE="${PWD}" +export INSTALL_PREFIX="${PWD}/install" +export LD_LIBRARY_PATH="${PWD}/install/lib" +export PKG_CONFIG_PATH="${PWD}/install/lib/pkgconfig" +ls -la ${GITHUB_WORKSPACE} +cd ${GITHUB_WORKSPACE} + +############################## +# Build RDKLogger # +############################## +echo "======================================================================================" +echo "buliding RDKLogger for coverity" +export + +cd ${GITHUB_WORKSPACE} +aclocal -I cfg +libtoolize --automake +autoheader +automake --foreign --add-missing +rm -f configure +autoconf +export ac_cv_func_malloc_0_nonnull=yes +export ac_cv_func_memset=yes +./configure "--prefix=${INSTALL_PREFIX}" +make +make install +echo "======================================================================================" +exit 0 diff --git a/doc/rdklogger-doxygen.cfg b/doc/rdklogger-doxygen.cfg index b00cf2d..45f1d0e 100644 --- a/doc/rdklogger-doxygen.cfg +++ b/doc/rdklogger-doxygen.cfg @@ -666,7 +666,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ./include/rdk_debug.h +INPUT = ./include/rdk_logger.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/include/Makefile.am b/include/Makefile.am index 5407b1e..340af64 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -19,4 +19,4 @@ SUBDIRS = librdkloggers_la_includedir = $(includedir) -librdkloggers_la_include_HEADERS = rdk_debug.h rdk_error.h rdk_logger_types.h rdk_logger_milestone.h +librdkloggers_la_include_HEADERS = rdk_logger.h rdk_debug.h rdk_error.h rdk_logger_types.h rdk_logger_milestone.h diff --git a/include/rdk_debug.h b/include/rdk_debug.h index 5234991..ade3708 100644 --- a/include/rdk_debug.h +++ b/include/rdk_debug.h @@ -22,290 +22,9 @@ * The header file provides RDK debug APIs. */ -/** - * @defgroup RDKLOGGER RDK Logger - * RDK Logger provides common logging capability for all RDK components. - * It is a common logging library which is based on MPEOS logging & uses log4c for - * formatting and supports multiple log levels. - * - * @par RDK Logger Capabilities - * - * - Abstracts logging client from underlying logging utility. - * - Dynamically enables/disables logging level at run time. - * - Provides logging format that complies with the existing OCAP format (e.g. [mod=*, level=*]). - * - Controls log level independently for each component/module. - * - Enables logging globally via single configuration value. - * - Controls initial log level for each component/module from configuration file (debug.ini) at startup. - * - The debug.ini is the main configuration file for RDK Logger and it is intended to be used - * globally in multi-process environment. - * - Prints formatted data to stdout. - * - Separates logs into separate files based on "SEPARATE.LOGFILE.SUPPORT" configuration variable. - * - RDK logger log files will be generated under "/opt/logs" folder if SEPARATE.LOGFILE.SUPPORT=TRUE - * - * @par How to add the RDK logger functionality to the new module? - * @n Include rdk_debug.h header file and make use of RDK_LOG for printing logs. Initialize RDK Logger by - * calling rdk_logger_init() in the respective module/component. Build new module/component by linking - * "librdkloggers.so" along with "liblog4c.so" and "libglib-2.0.so" shared object. - * @code - * Example: -lrdkloggers -L ../opensource/lib -llog4c -lglib-2.0 - * @endcode - * - * @par RDK Logger Usage - * @code - * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) - * @endcode - * - "level" is Log level of the log message (FATAL, ERROR etc). Apart from this there are - * special log levels like ALL, NONE, TRACE, !TRACE are supported. - * - "module" is the Module to which this message belongs to (Use module name same as mentioned in debug.ini) - * - "format" is a printf style string containing the log message. - * @n All the RDK components logs are stored under /opt/log/ with a naming convention _log.txt. - * @n For example, /opt/log/pod_log.txt includes all events logged by POD Manager module. - * - * @par Sample code for Logging: - * For example, add a debug messages for "INBSI" module - * @code - * RDK_LOG (RDK_LOG_NOTICE, "LOG.RDK.INBSI","<%s: %s>: Sending PMT_ACQUIRED event\n", PSIMODULE, __FUNCTION__); - * @endcode - * User needs to provide the module name "LOG.RDK.INBSI", which is the same as mentioned in debug.ini - * @code - * $ cat debug.ini - * EnableMPELog = TRUE - * LOG.RDK.INBSI = ALL FATAL ERROR WARNING NOTICE INFO DEBUG - * @endcode - * - * @par Sample logging output: - * @code - * 131011-21:21:49.578394 [mod=INBSI, lvl=NOTICE] [tid=4141] : Sending PMT_ACQUIRED event - * @endcode - * In this way, user make use of the RDK logger in the respective modules and control the logging levels through configuration file. - * Here, No need to build RDK logger again for the addition of new components/module. - * @ingroup RDKLOGGER - * - * @par How GStreamer logging - * - A callback function gst_debug_add_log_function() is registered to receive gstreamer logs. - * - Logs are converted to RDK logs in callback function. - * - RMF element which controls a gst-element shall register element name and corresponding log module using - * void RMF_registerGstElementDbgModule(char *gst_module, char *rmf_module) - * - Callback function uses this information to get module names corresponding to gstreamer logs. - * - * @par RDK Logging architecture - * - * @image html rdk_logger_architecture.jpg - * - * @par RDK Logging Configuration - * @n Default level of logging is ERROR. Logging settings are configured in debug.ini - * @code - * - LOG.RDK. = FATAL ERROR WARNING NOTICE INFO - * - LOG.RDK. = FATAL ERROR WARNING NOTICE INFO DEBUG - * @endcode - * - * @details Default log level entries for each modules are present in the debug.ini - * These entries are read at startup and can be modifiy/add as per the requirement. - * @details Bydefault logs are redirected to /opt/logs/ocapri_log.txt. - * But these can be configure to capture logs for each component in separate files under - * /opt/logs/ by setting configuration parameter SEPARATE.LOGFILE.SUPPORT as TRUE in - * debug.ini - * @details Following logs files generated if SEPARATE.LOGFILE.SUPPORT=TRUE - * - * For POD: pod_log.txt - * - * For CANH Daemon: canh_log.txt - * - * For RMFStreamer: rmfstr_log.txt - * - * @par Logging Levels supported by RDK Logger. - * Code | Description - * -----|------------ - * RDK_LOG_FATAL | Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss), reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss. - * RDK_LOG_ERROR | Any error which is fatal to the operation but not the service (cant open a file, missing data, etc) - * RDK_LOG_WARN | Anything that can potentially cause application oddities, but for which the application automatically recoverring. - * RDK_LOG_NOTICE | Anything that largely superfluous for application-level logging. - * RDK_LOG_INFO | Generally useful information to log (service start/stop, configuration assumptions, etc). - * RDK_LOG_DEBUG | Information that is diagnostically helpful to people more than just developers. - * RDK_LOG_TRACE | Only when it would be "tracing" the code and trying to find one part of a function specifically. - * - * @par How log files are upload to server - * @image html rdk_logupload.jpg - * - * @defgroup RDKLOGGER_DEBUG_API RDK Logger APIs - * Describe the details about RDK debug APIs specifications. - * @ingroup RDKLOGGER - * - * @defgroup RDKLOGGER_UTILS_API RDK Logger Utils APIs - * Describe the details about RDK Logger utils API specifications. - * @ingroup RDKLOGGER - */ - -/** -* @defgroup rdk_logger -* @{ -* @defgroup include -* @{ -**/ - - -#ifndef _RDK_DEBUG_H_ +#ifndef _RDK_DEBUG_H #define _RDK_DEBUG_H_ -#include -#include "rdk_logger_types.h" -#include "rdk_error.h" -#ifdef __cplusplus -extern "C" -{ -#endif - - -/** -* Macros for ease of applications using RDK_LOGGER apis -*/ - -/** - * Define the default location of configuration file location - */ -#define DEBUG_INI_NAME "/etc/debug.ini" - -/** - * Support for overriding debug.ini file location - */ -#ifndef DEBUG_INI_OVERRIDE_PATH -#define DEBUG_INI_OVERRIDE_PATH "/nvram/debug.ini" -#endif - -/** - * Support for Init function - */ -#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ - ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ - : rdk_logger_init(DEBUG_INI_NAME); -/** - * Use RDK_LOG debug message as. - * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) - * @param level Log level of the log message - * @param module Module in which this message belongs to (Use module name same as mentioned in debug.ini) - * @param format Printf style string containing the log message. - */ -#define RDK_LOG rdk_logger_msg_printf -#define RDK_LOG1 rdk_logger_msg_vsprintf - -/** - * Define the max length for the log file capture - */ -#define RDK_LOGGER_EXT_FILENAME_SIZE 32 - -/** - * Define the max length for the log capture path - */ -#define RDK_LOGGER_EXT_LOGDIR_SIZE 32 - -/** - * To allow compatibility of mutiple legacy RDK components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 - */ -#define RDK_LOG_TRACE1 RDK_LOG_TRACE -#define RDK_LOG_TRACE2 RDK_LOG_TRACE -#define RDK_LOG_TRACE3 RDK_LOG_TRACE -#define RDK_LOG_TRACE4 RDK_LOG_TRACE -#define RDK_LOG_TRACE5 RDK_LOG_TRACE -#define RDK_LOG_TRACE6 RDK_LOG_TRACE -#define RDK_LOG_TRACE7 RDK_LOG_TRACE -#define RDK_LOG_TRACE8 RDK_LOG_TRACE -#define RDK_LOG_TRACE9 RDK_LOG_TRACE - -/** - * An access function macro to check logging is enabled or not - */ -#define rdk_dbg_enabled rdk_logger_is_logLevel_enabled - -/** - * @enum rdk_LogLevel - * @brief These values represent the logging 'levels' or 'types', they are each - * independent. - */ -typedef enum -{ - RDK_LOG_FATAL = 0, - RDK_LOG_ERROR, - RDK_LOG_WARN, - RDK_LOG_NOTICE, - RDK_LOG_INFO, - RDK_LOG_DEBUG, - RDK_LOG_TRACE, - RDK_LOG_NONE -} rdk_LogLevel; - -typedef struct rdk_logger_ext_config_t - { - char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; - char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; - long maxSize; - long maxCount; - }rdk_logger_ext_config_t; - -/** - * @brief Initialize the RDK Logger. - * @param debugConfigFile Path to the debug.ini configuration file. - * @return RDK_SUCCESS on success, error code otherwise. - */ -rdk_Error rdk_logger_init(const char* debugConfigFile); - -/** - * @brief Extended initialization for RDK Logger. - * @param config Pointer to rdk_logger_ext_config_t structure. - * @return RDK_SUCCESS on success, error code otherwise. - */ -rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config); - -/** - * @brief Deinitialize the RDK Logger. - * @return RDK_SUCCESS on success, error code otherwise. - */ -rdk_Error rdk_logger_deinit(void); - -/** - * @brief Log a message with printf-style formatting. - * @param level Log level. - * @param module Module name. - * @param format Printf-style format string. - */ -void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...); - -/** - * @brief Log a message using a va_list. - * @param level Log level. - * @param module Module name. - * @param format Printf-style format string. - * @param args va_list of arguments. - */ -void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args); - -/** - * @brief Check if a log level is enabled for a module. - * @param module Module name. - * @param level Log level. - * @return TRUE if enabled, FALSE otherwise. - */ -rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); - -/** - * @brief Enable or disable a log level for a module. - * @param module Module name. - * @param logLevel Log level. - * @param enableLogLvl TRUE to enable, FALSE to disable. - * @return TRUE if successful, FALSE otherwise. - */ -rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); - -/** - * @brief Log a message for onboard logging. - * @param module Module name. - * @param msg Message to log. - */ -void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribute__ ((format (printf, 2, 3))); - -/** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API - -#ifdef __cplusplus -} -#endif +#include "rdk_logger.h" #endif /* _RDK_DEBUG_H_ */ diff --git a/include/rdk_logger.h b/include/rdk_logger.h new file mode 100644 index 0000000..4048c21 --- /dev/null +++ b/include/rdk_logger.h @@ -0,0 +1,293 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/** + * @file rdk_logger.h + * The header file provides RDK Logger APIs. + */ + +/** + * @defgroup RDKLOGGER RDK Logger + * RDK Logger provides common logging capability for all RDK components. + * It is a common logging library which is based on MPEOS logging & uses log4c for + * formatting and supports multiple log levels. + * + * @par RDK Logger Capabilities + * + * - Abstracts logging client from underlying logging utility. + * - Dynamically enables/disables logging level at run time. + * - Provides logging format that complies with the existing OCAP format (e.g. [mod=*, level=*]). + * - Controls log level independently for each component/module. + * - Enables logging globally via single configuration value. + * - Controls initial log level for each component/module from configuration file (debug.ini) at startup. + * - The debug.ini is the main configuration file for RDK Logger and it is intended to be used + * globally in multi-process environment. + * - Prints formatted data to stdout. + * + * @par How to add the RDK logger functionality to the new module? + * @n Include rdk_logger.h header file and make use of RDK_LOG for printing logs. Initialize RDK Logger by + * calling rdk_logger_init() in the respective module/component. Build new module/component by linking + * "librdkloggers.so" along with "liblog4c.so" and "libglib-2.0.so" shared object. + * @code + * Example: -lrdkloggers -L ../opensource/lib -llog4c -lglib-2.0 + * @endcode + * + * @par RDK Logger Usage + * @code + * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) + * @endcode + * - "level" is Log level of the log message (FATAL, ERROR etc). Apart from this there are + * special log levels like ALL, NONE, TRACE, !TRACE are supported. + * - "module" is the Module to which this message belongs to (Use module name same as mentioned in debug.ini) + * - "format" is a printf style string containing the log message. + * + * @par Sample code for Logging: + * For example, add a debug messages for "SI" module + * @code + * RDK_LOG (RDK_LOG_NOTICE, "LOG.RDK.SI","<%s: %s>: Sending PMT_ACQUIRED event\n", PSIMODULE, __FUNCTION__); + * @endcode + * + * @par Sample logging output: + * @code + * 131011-21:21:49.578394 [mod=INBSI, lvl=NOTICE] [tid=4141] : Sending PMT_ACQUIRED event + * @endcode + * + * In this way, user make use of the RDK logger in the respective modules and control the logging levels through configuration file. + * Here, No need to build RDK logger again for the addition of new components/module. + * @ingroup RDKLOGGER + * + * @par RDK Logging architecture + * + * @image html rdk_logger_architecture.jpg + * + * @par RDK Logging Configuration + * @n Default level of logging is WARNING. Logging settings can be overriden by debug.ini + * @code + * - LOG.RDK. = INFO + * - LOG.RDK. = DEBUG + * @endcode + * + * @par Logging Levels supported by RDK Logger. + * Code | Description + * -----|------------ + * RDK_LOG_FATAL | Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss), reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss. + * RDK_LOG_ERROR | Any error which is fatal to the operation but not the service (cant open a file, missing data, etc) + * RDK_LOG_WARN | Anything that can potentially cause application oddities, but for which the application automatically recoverring. + * RDK_LOG_NOTICE | Anything that largely superfluous for application-level logging. + * RDK_LOG_INFO | Generally useful information to log (service start/stop, configuration assumptions, etc). + * RDK_LOG_DEBUG | Information that is diagnostically helpful to people more than just developers. + * RDK_LOG_TRACE | Only when it would be "tracing" the code and trying to find one part of a function specifically. + * + * @par How log files are upload to server + * @image html rdk_logupload.jpg + * + * @defgroup RDKLOGGER_LOGGER_API RDK Logger APIs + * Describe the details about RDK Logger APIs specifications. + * @ingroup RDKLOGGER + * + * @defgroup RDKLOGGER_UTILS_API RDK Logger Utils APIs + * Describe the details about RDK Logger utils API specifications. + * @ingroup RDKLOGGER + */ + +/** +* @defgroup rdk_logger +* @{ +* @defgroup include +* @{ +**/ + + +#ifndef _RDK_LOGGER_H_ +#define _RDK_LOGGER_H_ + +#include +#include "rdk_logger_types.h" +#include "rdk_error.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** +* Macros for ease of applications using RDK_LOGGER apis +*/ + +/** + * Define the default location of configuration file location + */ +#define DEBUG_INI_NAME "/etc/debug.ini" + +/** + * Support for overriding debug.ini file location + */ +#ifndef DEBUG_INI_OVERRIDE_PATH +#define DEBUG_INI_OVERRIDE_PATH "/nvram/debug.ini" +#endif + +/** + * Support for Init function + */ +#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ + ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ + : rdk_logger_init(DEBUG_INI_NAME); +/** + * Use RDK_LOG debug message as. + * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) + * @param level Log level of the log message + * @param module Module in which this message belongs to (Use module name same as mentioned in debug.ini) + * @param format Printf style string containing the log message. + */ +#define RDK_LOG rdk_logger_msg_printf +#define RDK_LOG1 rdk_logger_msg_vsprintf +/** + * Define the max length for the log file capture + */ +#define RDK_LOGGER_EXT_FILENAME_SIZE 32 + +/** + * Define the max length for the log capture path + */ +#define RDK_LOGGER_EXT_LOGDIR_SIZE 32 + +/** + * To allow compatibility of mutiple legacy RDK components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 + */ +#define RDK_LOG_TRACE1 RDK_LOG_TRACE +#define RDK_LOG_TRACE2 RDK_LOG_TRACE +#define RDK_LOG_TRACE3 RDK_LOG_TRACE +#define RDK_LOG_TRACE4 RDK_LOG_TRACE +#define RDK_LOG_TRACE5 RDK_LOG_TRACE +#define RDK_LOG_TRACE6 RDK_LOG_TRACE +#define RDK_LOG_TRACE7 RDK_LOG_TRACE +#define RDK_LOG_TRACE8 RDK_LOG_TRACE +#define RDK_LOG_TRACE9 RDK_LOG_TRACE + +/** + * An access function macro to check logging is enabled or not + */ +#define rdk_dbg_enabled rdk_logger_is_logLevel_enabled + +/** + * To allow compatibility of mutiple legacy RDK components using onboard API + */ +#define rdk_log_onboard rdk_logger_log_onboard + +/** + * @enum rdk_LogLevel + * @brief These values represent the logging 'levels' or 'types', they are each + * independent. + */ +typedef enum +{ + RDK_LOG_FATAL = 0, + RDK_LOG_ERROR, + RDK_LOG_WARN, + RDK_LOG_NOTICE, + RDK_LOG_INFO, + RDK_LOG_DEBUG, + RDK_LOG_TRACE, + RDK_LOG_NONE +} rdk_LogLevel; + +typedef struct rdk_logger_ext_config_t + { + char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; + char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; + long maxSize; + long maxCount; + }rdk_logger_ext_config_t; + +/** + * @brief Initialize the RDK Logger. + * @param debugConfigFile Path to the debug.ini configuration file. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_init(const char* debugConfigFile); + +/** + * @brief Extended initialization for RDK Logger. + * @param config Pointer to rdk_logger_ext_config_t structure. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config); + +/** + * @brief Deinitialize the RDK Logger. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_deinit(void); + +/** + * @brief Log a message with printf-style formatting. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + */ +void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); + +/** + * @brief Log a message using a va_list. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + * @param args va_list of arguments. + */ +void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args); + +/** + * @brief Check if a log level is enabled for a module. + * @param module Module name. + * @param level Log level. + * @return TRUE if enabled, FALSE otherwise. + */ +rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); + +/** + * @brief Enable or disable a log level for a module. + * @param module Module name. + * @param logLevel Log level. + * @param enableLogLvl TRUE to enable, FALSE to disable. + * @return TRUE if successful, FALSE otherwise. + */ +rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); + +/** + * @brief Log a message for onboard logging. + * @param module Module name. + * @param msg Message to log. + */ +void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribute__ ((format (printf, 2, 3))); + +/** + * @brief legacy method to Log a message with printf-style formatting; + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + */ +void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); + +/** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API + +#ifdef __cplusplus +} +#endif + +#endif /* _RDK_LOGGER_H_ */ diff --git a/src/include/rdk_utils.h b/include/rdk_utils.h similarity index 100% rename from src/include/rdk_utils.h rename to include/rdk_utils.h diff --git a/src/Makefile.am b/src/Makefile.am index 811b395..feb50a3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,9 +20,7 @@ AM_CPPFLAGS = -pthread -Wall lib_LTLIBRARIES = librdkloggers.la librdkloggers_la_SOURCES = rdk_debug.c rdk_debug_priv.c rdk_dynamic_logger.c rdk_logger_init.c rdk_logger_util.c rdk_logger_milestone.cpp -if IS_ONBOARDLOG_ENABLED librdkloggers_la_SOURCES += rdk_logger_onboard.c -endif librdkloggers_la_CFLAGS = $(LOG4C_CFLAGS) $(GLIB_CFLAGS) $(SYSLOG_HELPER_CFLAGS) $(SYSTEMD_CLFAGS) -I./include -I../include -I${RDK_PROJECT_ROOT_PATH}/opensource/include/log4c -I${RDK_PROJECT_ROOT_PATH}/opensource/include -DDEBUG_CONF_FILE="\"debug.ini\"" librdkloggers_la_LDFLAGS = $(GLIB_LIBS) $(LOG4C_LIBS) $(SYSLOG_HELPER_LDFLAGS) $(SYSTEMD_LDFLAGS) librdkloggers_la_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/include -I$(top_srcdir)/include diff --git a/src/include/rdk_debug_priv.h b/src/include/rdk_debug_priv.h index b2b71c4..57fe31c 100644 --- a/src/include/rdk_debug_priv.h +++ b/src/include/rdk_debug_priv.h @@ -21,7 +21,7 @@ #define _RDK_DBG_PRIV_H #include -#include +#include #include #ifdef __cplusplus diff --git a/src/include/rdk_dynamic_logger.h b/src/include/rdk_dynamic_logger.h index e087e0a..2be2cdd 100644 --- a/src/include/rdk_dynamic_logger.h +++ b/src/include/rdk_dynamic_logger.h @@ -20,7 +20,7 @@ #if !defined(_RDK_DBG_PRIV_DYNLOG_H) #define _RDK_DBG_PRIV_DYNLOG_H -#include +#include void rdk_dyn_log_init(void); void rdk_dyn_log_deinit(void); diff --git a/src/rdk_debug.c b/src/rdk_debug.c index a78d0b0..a33521a 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -30,7 +30,7 @@ **/ -#include +#include #include #include // memset @@ -71,7 +71,23 @@ void rdk_dbg_deinit() */ void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...) { - int num; + va_list args; + + va_start(args, format); + rdk_dbg_priv_log_msg(level, module, format, args); + va_end(args); +} + +/** + * @brief Send a debugging message to the debugging window. It is appended to the log output based + * on configurations set in the environment file. + * + * @param[in] level The debug logging level. + * @param[in] module The name of the module for which this message belongs to, it is mentioned in debug.ini. + * @param[in] format Printf style string containing the log message. + */ +void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, ...) +{ va_list args; va_start(args, format); diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index 0e6ba8a..8430d9a 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -297,6 +297,7 @@ static void printTime(const struct tm *pTm, char *pBuff) ****************************************************************************/ void rdk_dbg_priv_config(void) { + int mod = 1; const char *defaultValue = rdk_logger_envGet("LOG.RDK.DEFAULT"); if (defaultValue && defaultValue[0] != 0) { @@ -334,7 +335,7 @@ void rdk_dbg_priv_config(void) return; } - for (int mod = 1; mod <= global_count; mod++) + for (mod = 1; mod <= global_count; mod++) { const char* modName = rdk_logger_envGetModFromNum(mod); const char* modValue = rdk_logger_envGetValueFromNum(mod); @@ -372,7 +373,7 @@ void rdk_dbg_priv_config(void) /** * @brief Function to check if a specific log level of a module is enabled. * - * @param[in] module The module name or category for for which the log level shall be checked (as mentioned in debug.ini). + * @param[in] module The module name or category for which the log level shall be checked (as mentioned in debug.ini). * @param[in] level The debug logging level. * * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. diff --git a/src/rdk_logger_init.c b/src/rdk_logger_init.c index 8ad825d..fd09f2d 100644 --- a/src/rdk_logger_init.c +++ b/src/rdk_logger_init.c @@ -35,7 +35,7 @@ #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "rdk_error.h" #include "rdk_debug_priv.h" #include "rdk_dynamic_logger.h" diff --git a/src/rdk_logger_onboard.c b/src/rdk_logger_onboard.c index f6ec8ca..ae35294 100644 --- a/src/rdk_logger_onboard.c +++ b/src/rdk_logger_onboard.c @@ -16,7 +16,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifdef FEATURE_SUPPORT_ONBOARD_LOGGING #include #include #include @@ -92,4 +91,3 @@ void rdk_logger_log_onboard(const char *module, const char *msg, ...) } } } -#endif diff --git a/src/rdk_logger_util.c b/src/rdk_logger_util.c index b95a671..1f2e6ac 100644 --- a/src/rdk_logger_util.c +++ b/src/rdk_logger_util.c @@ -28,7 +28,7 @@ /* Header Files */ #include /* Resolve basic type references. */ -#include "rdk_debug.h" /* Resolved RDK_LOG support. */ +#include "rdk_logger.h" /* Resolved RDK_LOG support. */ #include "rdk_error.h" #include "rdk_utils.h" diff --git a/test/rdk_logger_debug_test.c b/test/rdk_logger_debug_test.c index 4dce53b..ac21bff 100644 --- a/test/rdk_logger_debug_test.c +++ b/test/rdk_logger_debug_test.c @@ -19,7 +19,7 @@ #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" int rdk_logger_debug_test() { RDK_LOG(RDK_LOG_FATAL, "LOG.RDK.GFX", diff --git a/test/rdk_logger_test_main.c b/test/rdk_logger_test_main.c index 6e7027a..b0e8649 100644 --- a/test/rdk_logger_test_main.c +++ b/test/rdk_logger_test_main.c @@ -18,7 +18,7 @@ */ #include -#include "rdk_debug.h" +#include "rdk_logger.h" int rdk_logger_debug_test(); diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index f11f652..37b9675 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -21,26 +21,9 @@ project(rdk_logger_gtest) # Find the gtest package find_package(GTest REQUIRED) -include_directories(${RDKLOGGER_SOURCE_PATH}/) -include_directories(${RDKLOGGER_SOURCE_PATH}/include) -include_directories(${RDKLOGGER_SOURCE_PATH}/src/include) -include_directories(${RDKLOGGER_SOURCE_PATH}/cfg) -include_directories(${RDKLOGGER_UNITTEST_DIR}/) - -# Set the path to the gtest installation directory -set(GTEST_ROOT "${RDKLOGGER_UNITTEST_DIR}/googletest/") - -# Add the test executable -#add_executable(unitTestRunner testRunner.cpp) - -# Link the gtest libraries to the test executable -#target_link_libraries(unitTestRunner GTest::GTest GTest::Main) - enable_testing() -link_directories("${RDKLOGGER_SOURCE_PATH}/src/.libs/") -link_directories("${DEP_LIB_PATH}/log4c-1.2.3/install/lib/") -link_directories("${RDKLOGGER_UNITTEST_DIR}/googletest/build/lib/") +link_directories("${DEP_LIB_PATH}/") # Add the test executable add_executable( @@ -51,15 +34,15 @@ add_executable( rdkIsDbgEnabled.cpp main.cpp ) -target_compile_definitions(rdk_logger_gtest PRIVATE GTEST_DEBUG_INI_FILE="${RDKLOGGER_UNITTEST_DIR}/sample_gtest_debug.ini") +target_compile_definitions(rdk_logger_gtest PRIVATE GTEST_DEBUG_INI_FILE="sample_gtest_debug.ini") -install (CODE "execute_process (COMMAND ${CMAKE_COMMAND} -E copy ${RDKLOGGER_UNITTEST_DIR}/Gtest_log4crc ${RDKLOGGER_UNITTEST_DIR}/build/log4crc)") +install (CODE "execute_process (COMMAND ${CMAKE_COMMAND} -E copy Gtest_log4crc ${CMAKE_INSTALL_PREFIX}/log4crc)") if (NOT GTEST_INCLUDE_DIR) - target_link_libraries(rdk_logger_gtest -L${RDKLOGGER_SOURCE_PATH}/src/.libs -lrdkloggers -L${DEP_LIB_PATH}/log4c-1.2.3/install/lib/ -llog4c -l:libgtest.a gcov) + target_link_libraries(rdk_logger_gtest -L${DEP_LIB_PATH} -lrdkloggers -llog4c -l:libgtest.a gcov) else () - target_link_libraries(rdk_logger_gtest -L${RDKLOGGER_SOURCE_PATH}/src/.lib -L${DEP_LIB_PATH}/log4c-1.2.3/install/lib/ rdkloggers log4c gtest gcov) + target_link_libraries(rdk_logger_gtest -L${DEP_LIB_PATH} -lrdkloggers -llog4c gtest gcov) endif() # Link the gtest libraries to the test executable @@ -68,11 +51,7 @@ target_link_libraries( GTest::gtest_main ) -message("RDKLOGGER_SOURCE_PATH ${RDKLOGGER_SOURCE_PATH} RDK_PROJECT_ROOT_PATH ${RDK_PROJECT_ROOT_PATH} RDKLOGGER_UNITTEST_DIR ${RDKLOGGER_UNITTEST_DIR}.") -include_directories(${RDKLOGGER_UNITTEST_DIR}/googletest/googletest/include) -include_directories(${RDKLOGGER_UNITTEST_DIR}/googletest/googletest/src) -include_directories(${RDKLOGGER_SOURCE_PATH}/include) -include_directories(${DEP_LIB_PATH}/log4c-1.2.3/src/log4c) +include_directories(${DEP_LIB_PATH}/../include) include(GoogleTest) gtest_discover_tests(rdk_logger_gtest) find_package(Threads) diff --git a/unittests/main.cpp b/unittests/main.cpp index 8d91a1f..e5973bb 100644 --- a/unittests/main.cpp +++ b/unittests/main.cpp @@ -18,7 +18,7 @@ */ #include "gtest/gtest.h" -char gtestReportPath[] = "xml:/tmp/Gtest_Report/rbus_gtest_report.xml"; +char gtestReportPath[] = "xml:/tmp/Gtest_Report/rdklogger_gtest_report.xml"; GTEST_API_ int main(int argc, char* argv[]) { diff --git a/unittests/rdkIsDbgEnabled.cpp b/unittests/rdkIsDbgEnabled.cpp index 2ebc96b..9befa11 100644 --- a/unittests/rdkIsDbgEnabled.cpp +++ b/unittests/rdkIsDbgEnabled.cpp @@ -22,7 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "gtest_app.h" #if 0 diff --git a/unittests/rdkloggerInit.cpp b/unittests/rdkloggerInit.cpp index 34ed43d..b595f90 100644 --- a/unittests/rdkloggerInit.cpp +++ b/unittests/rdkloggerInit.cpp @@ -22,7 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "gtest_app.h" /*DIABLED some test cases as there's a bug "https://bugzilla.redhat.com/show_bug.cgi?id=1901955" in log4c library, calling log4c_init twice causing segmentation fault, hence keeping rdk_logger_deinit()'s default changes which does not allow calling rdk_logger_init twice*/ diff --git a/unittests/rdkloggerMsgPrintf.cpp b/unittests/rdkloggerMsgPrintf.cpp index 606164f..6471917 100644 --- a/unittests/rdkloggerMsgPrintf.cpp +++ b/unittests/rdkloggerMsgPrintf.cpp @@ -22,7 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "gtest_app.h" TEST(rdkloggerMsgPrintf, logModule_ONLYFATAL_output_to_file) diff --git a/unittests/rdkloggerMsgVsprintf.cpp b/unittests/rdkloggerMsgVsprintf.cpp index 83b6d69..7d53ae9 100644 --- a/unittests/rdkloggerMsgVsprintf.cpp +++ b/unittests/rdkloggerMsgVsprintf.cpp @@ -22,7 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "gtest_app.h" void gtest_rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *mod, const char *format, ...) diff --git a/utils/Makefile.am b/utils/Makefile.am index e96182a..098858d 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -21,19 +21,17 @@ bin_PROGRAMS = rdklogctrl rdklogctrl_SOURCES=rdklogctrl.c rdklogctrl_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/include -I./usr/include -rdklogctrl_LDFLAGS = -I./usr/lib +rdklogctrl_LDFLAGS = -L/usr/lib -if IS_MILESTONE_ENABLED bin_PROGRAMS += rdkLogMileStone rdkLogMileStone_SOURCES = rdklogmilestone.c -rdkLogMileStone_LDADD = $(top_builddir)/src/librdkloggers.la +rdkLogMileStone_LDADD = $(top_builddir)/src/librdkloggers.la $(LOG4C_LIBS) rdkLogMileStone_CFLAGS = -I$(top_srcdir)/include -endif +rdkLogMileStone_LDFLAGS = -L/usr/lib -if IS_ONBOARDLOG_ENABLED -bin_PROGRAMS = onboarding_log + +bin_PROGRAMS += onboarding_log onboarding_log_SOURCES = rdk_logger_onboard_main.c -onboarding_log_LDADD = $(top_builddir)/src/librdkloggers.la +onboarding_log_LDADD = $(top_builddir)/src/librdkloggers.la $(LOG4C_LIBS) onboarding_log_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/include -I./usr/include -onboarding_log_LDFLAGS = -I./usr/lib -endif +onboarding_log_LDFLAGS = -L/usr/lib diff --git a/utils/rdk_logger_onboard_main.c b/utils/rdk_logger_onboard_main.c index 49bffaf..40788e3 100644 --- a/utils/rdk_logger_onboard_main.c +++ b/utils/rdk_logger_onboard_main.c @@ -16,11 +16,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifdef FEATURE_SUPPORT_ONBOARD_LOGGING #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #define MAX_BUF_SIZE 1024 @@ -40,4 +39,3 @@ int main( int argc, char **argv) return 0; } -#endif From 6f16c071ad6eb3d4ca32da56bdfa13486f004e45 Mon Sep 17 00:00:00 2001 From: Karunakaran A Date: Mon, 1 Sep 2025 13:07:16 -0400 Subject: [PATCH 09/37] Release of RDKLogger v2.1.0 Release of RDKLogger v2.1.0 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 146a1f4..b9dcf09 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 2.0.0) +AC_INIT(rdklogger, 2.1.0) AC_CONFIG_SRCDIR([src]) AM_CONFIG_HEADER(cfg/config.h) AC_CONFIG_MACRO_DIR([cfg]) From 7b1e5cf724d30c7c812e8b980241d105441c9aa9 Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Mon, 1 Sep 2025 21:00:01 +0530 Subject: [PATCH 10/37] RDKB-60970: RDKLogger OpenSource Migration (#20) * RDKB-60970: RDKLogger OpenSource Migration Reason for change: To fix compilation errors Test Procedure: Tested and verified Risks:Medium Priority:P1 Signed-off-by: dshett549 Signed-off-by: karunakaran_amirthalingam --- .github/workflows/L1-tests.yml | 18 +- build_dependencies.sh | 26 +++ config.mak | 58 ------ cov_build.sh | 34 ++++ doc/rdklogger-doxygen.cfg | 2 +- include/Makefile.am | 2 +- include/rdk_debug.h | 285 +------------------------- include/rdk_logger.h | 293 +++++++++++++++++++++++++++ {src/include => include}/rdk_utils.h | 0 src/Makefile.am | 2 - src/include/rdk_debug_priv.h | 2 +- src/include/rdk_dynamic_logger.h | 2 +- src/rdk_debug.c | 20 +- src/rdk_debug_priv.c | 5 +- src/rdk_logger_init.c | 2 +- src/rdk_logger_onboard.c | 2 - src/rdk_logger_util.c | 2 +- test/rdk_logger_debug_test.c | 2 +- test/rdk_logger_test_main.c | 2 +- unittests/CMakeLists.txt | 33 +-- unittests/main.cpp | 2 +- unittests/rdkIsDbgEnabled.cpp | 2 +- unittests/rdkloggerInit.cpp | 2 +- unittests/rdkloggerMsgPrintf.cpp | 2 +- unittests/rdkloggerMsgVsprintf.cpp | 2 +- utils/Makefile.am | 16 +- utils/rdk_logger_onboard_main.c | 4 +- 27 files changed, 412 insertions(+), 410 deletions(-) create mode 100755 build_dependencies.sh delete mode 100644 config.mak create mode 100755 cov_build.sh create mode 100644 include/rdk_logger.h rename {src/include => include}/rdk_utils.h (100%) diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index f8a0363..3891817 100644 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -2,15 +2,17 @@ name: l1-tests on: push: - branches: [ main, 'release/**', develop, 'topic/**' ] + branches: [ main, 'release/**', develop, 'topic/**', 'support/**' ] pull_request: - branches: [ main, 'release/**', develop, 'topic/**' ] + branches: [ main, 'release/**', develop, 'topic/**', 'support/**' ] env: WORK_DIR: ${{github.workspace}} DEP_LIB: ${{github.workspace}}/dep_lib RDKLOGGER_ROOT: ${{github.workspace}}/Rdklogger - RDKLOGGER_INSTALL_DIR: ${{github.workspace}}/Rdklogger/install + LD_LIBRARY_PATH: ${{github.workspace}}/install/lib + PKG_CONFIG_PATH: ${{github.workspace}}/install/lib/pkgconfig + RDKLOGGER_PREFIX: ${{github.workspace}}/install jobs: l1-tests: @@ -68,7 +70,7 @@ jobs: tar -xzf log4c-1.2.3.tar.gz fi cd "log4c-1.2.3" - ./configure "--prefix=${DEP_LIB}/log4c-1.2.3/install" + ./configure "--prefix=${{github.workspace}}/install" make make install @@ -83,9 +85,7 @@ jobs: autoconf export ac_cv_func_malloc_0_nonnull=yes export ac_cv_func_memset=yes - export LOG4C_CFLAGS="-I${{env.DEP_LIB}}/log4c-1.2.3/install/include/log4c/ -I${{env.DEP_LIB}}/log4c-1.2.3/src/ -I${{env.DEP_LIB}}/log4c-1.2.3/src/log4c -I${{env.DEP_LIB}}/log4c-1.2.3/install/include/" - export LOG4C_LIBS="-L${{env.DEP_LIB}}/log4c-1.2.3/install/lib" - ./configure --prefix=${{env.RDKLOGGER_INSTALL_DIR}}/lib --sysconfdir=${{env.RDKLOGGER_INSTALL_DIR}}/bin LOG4c_CFLAGS="-I${{env.DEP_LIB}}/log4c-1.2.3/src/ -I${{env.DEP_LIB}}/log4c-1.2.3/install/include/log4c/" LOG4C_LIBS="-L${{env.DEP_LIB}}/log4c-1.2.3/install/lib/liblog4c.so" + ./configure "--prefix=${{github.workspace}}/install" make make install @@ -94,7 +94,7 @@ jobs: mkdir -p ${{env.RDKLOGGER_ROOT}}/unittests UNITTESTS="${{env.RDKLOGGER_ROOT}}/unittests" cd ${UNITTESTS} - cmake -DRDKLOGGER_SOURCE_PATH=${{env.RDKLOGGER_ROOT}} -DDEP_LIB_PATH=${{env.DEP_LIB}} -DRDKLOGGER_UNITTEST_DIR=${UNITTESTS} -DCMAKE_INSTALL_PREFIX:PATH=${UNITTESTS}/build -DDEBUG_CONF_FILE="\"debug.ini\"" -S . -B build - make -C build + cmake -B build -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install/usr -DDEP_LIB_PATH=${{env.LD_LIBRARY_PATH}} -DCMAKE_VERBOSE_MAKEFILE=ON + make -C build cmake --install build ./build/rdk_logger_gtest diff --git a/build_dependencies.sh b/build_dependencies.sh new file mode 100755 index 0000000..aad865f --- /dev/null +++ b/build_dependencies.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e +set -x + +############################## +# Setup WorkSpace # +############################## +GITHUB_WORKSPACE="${PWD}" +export INSTALL_PREFIX="${PWD}/install" +export LD_LIBRARY_PATH="${PWD}/install/lib" +export PKG_CONFIG_PATH="${PWD}/install/lib/pkgconfig" +ls -la ${GITHUB_WORKSPACE} +cd ${GITHUB_WORKSPACE} + +####################################### +# Install Dependencies and packages # +####################################### +apt update && apt install -y libcurl4-openssl-dev libgtest-dev lcov gcovr libmsgpack* build-essential + +wget https://sourceforge.net/projects/log4c/files/log4c/1.2.3/log4c-1.2.3.tar.gz +tar -xzf log4c-1.2.3.tar.gz +cd "log4c-1.2.3" +./configure "--prefix=${INSTALL_PREFIX}" +make +make install + diff --git a/config.mak b/config.mak deleted file mode 100644 index 2eebe02..0000000 --- a/config.mak +++ /dev/null @@ -1,58 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -#Please make sure that -# 1. PLATFORM_SDK, -# 2. RDK_DIR are exported properly before using this file - -#Path of directory containing configuration files in STB. If commented, application expects config files to be present in working directory. -#CONFIG_DIR=/config -#Configuration flags. Comment the definition for disabling and uncomment for enabling. - - -CFLAGS?= -g -Wno-format -Wunused - -ifdef CONFIG_DIR - CONFIG_PREFIX=$(CONFIG_DIR)/ -endif - - -CFLAGS += -DDEBUG_CONF_FILE="\"$(CONFIG_PREFIX)debug.ini\"" - -ARFLAGS=rcs -BUILD_DIR=$(RDK_LOGGER_DIR)/build -LIBDIR=$(BUILD_DIR)/lib - -LOGGER_INCL=$(RDK_LOGGER_DIR)/include - --include $(RDK_LOGGER_DIR)/soc/build/config.mak - -INCLUDES=-I$(LOGGER_INCL)\ - -I$(RDK_LOGGER_DIR)/../core\ - -I$(PLATFORM_SDK)/include/ \ - -I$(PLATFORM_SDK)/include/gstreamer-0.10 \ - -I$(PLATFORM_SDK)/include/glib-2.0 \ - -I$(PLATFORM_SDK)/lib/glib-2.0/include \ - -I$(PLATFORM_SDK)/usr/include/ \ - -I$(PLATFORM_SDK)/include/libxml2 \ - -I$(RDK_DIR)/opensource/include/libxml2 \ - -I$(RDK_DIR)/opensource/include/gstreamer-0.10 \ - -I$(RDK_DIR)/opensource/include/glib-2.0 \ - -I$(RDK_DIR)/opensource/include/ \ - -I$(RDK_DIR)/opensource/lib/glib-2.0/include \ - -I$(PLATFORM_SDK)/include/linux_user diff --git a/cov_build.sh b/cov_build.sh new file mode 100755 index 0000000..447a808 --- /dev/null +++ b/cov_build.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -e +set -x +############################## +# Setup WorkSpace # +############################## +GITHUB_WORKSPACE="${PWD}" +export INSTALL_PREFIX="${PWD}/install" +export LD_LIBRARY_PATH="${PWD}/install/lib" +export PKG_CONFIG_PATH="${PWD}/install/lib/pkgconfig" +ls -la ${GITHUB_WORKSPACE} +cd ${GITHUB_WORKSPACE} + +############################## +# Build RDKLogger # +############################## +echo "======================================================================================" +echo "buliding RDKLogger for coverity" +export + +cd ${GITHUB_WORKSPACE} +aclocal -I cfg +libtoolize --automake +autoheader +automake --foreign --add-missing +rm -f configure +autoconf +export ac_cv_func_malloc_0_nonnull=yes +export ac_cv_func_memset=yes +./configure "--prefix=${INSTALL_PREFIX}" +make +make install +echo "======================================================================================" +exit 0 diff --git a/doc/rdklogger-doxygen.cfg b/doc/rdklogger-doxygen.cfg index b00cf2d..45f1d0e 100644 --- a/doc/rdklogger-doxygen.cfg +++ b/doc/rdklogger-doxygen.cfg @@ -666,7 +666,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ./include/rdk_debug.h +INPUT = ./include/rdk_logger.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/include/Makefile.am b/include/Makefile.am index 5407b1e..340af64 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -19,4 +19,4 @@ SUBDIRS = librdkloggers_la_includedir = $(includedir) -librdkloggers_la_include_HEADERS = rdk_debug.h rdk_error.h rdk_logger_types.h rdk_logger_milestone.h +librdkloggers_la_include_HEADERS = rdk_logger.h rdk_debug.h rdk_error.h rdk_logger_types.h rdk_logger_milestone.h diff --git a/include/rdk_debug.h b/include/rdk_debug.h index 5234991..ade3708 100644 --- a/include/rdk_debug.h +++ b/include/rdk_debug.h @@ -22,290 +22,9 @@ * The header file provides RDK debug APIs. */ -/** - * @defgroup RDKLOGGER RDK Logger - * RDK Logger provides common logging capability for all RDK components. - * It is a common logging library which is based on MPEOS logging & uses log4c for - * formatting and supports multiple log levels. - * - * @par RDK Logger Capabilities - * - * - Abstracts logging client from underlying logging utility. - * - Dynamically enables/disables logging level at run time. - * - Provides logging format that complies with the existing OCAP format (e.g. [mod=*, level=*]). - * - Controls log level independently for each component/module. - * - Enables logging globally via single configuration value. - * - Controls initial log level for each component/module from configuration file (debug.ini) at startup. - * - The debug.ini is the main configuration file for RDK Logger and it is intended to be used - * globally in multi-process environment. - * - Prints formatted data to stdout. - * - Separates logs into separate files based on "SEPARATE.LOGFILE.SUPPORT" configuration variable. - * - RDK logger log files will be generated under "/opt/logs" folder if SEPARATE.LOGFILE.SUPPORT=TRUE - * - * @par How to add the RDK logger functionality to the new module? - * @n Include rdk_debug.h header file and make use of RDK_LOG for printing logs. Initialize RDK Logger by - * calling rdk_logger_init() in the respective module/component. Build new module/component by linking - * "librdkloggers.so" along with "liblog4c.so" and "libglib-2.0.so" shared object. - * @code - * Example: -lrdkloggers -L ../opensource/lib -llog4c -lglib-2.0 - * @endcode - * - * @par RDK Logger Usage - * @code - * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) - * @endcode - * - "level" is Log level of the log message (FATAL, ERROR etc). Apart from this there are - * special log levels like ALL, NONE, TRACE, !TRACE are supported. - * - "module" is the Module to which this message belongs to (Use module name same as mentioned in debug.ini) - * - "format" is a printf style string containing the log message. - * @n All the RDK components logs are stored under /opt/log/ with a naming convention _log.txt. - * @n For example, /opt/log/pod_log.txt includes all events logged by POD Manager module. - * - * @par Sample code for Logging: - * For example, add a debug messages for "INBSI" module - * @code - * RDK_LOG (RDK_LOG_NOTICE, "LOG.RDK.INBSI","<%s: %s>: Sending PMT_ACQUIRED event\n", PSIMODULE, __FUNCTION__); - * @endcode - * User needs to provide the module name "LOG.RDK.INBSI", which is the same as mentioned in debug.ini - * @code - * $ cat debug.ini - * EnableMPELog = TRUE - * LOG.RDK.INBSI = ALL FATAL ERROR WARNING NOTICE INFO DEBUG - * @endcode - * - * @par Sample logging output: - * @code - * 131011-21:21:49.578394 [mod=INBSI, lvl=NOTICE] [tid=4141] : Sending PMT_ACQUIRED event - * @endcode - * In this way, user make use of the RDK logger in the respective modules and control the logging levels through configuration file. - * Here, No need to build RDK logger again for the addition of new components/module. - * @ingroup RDKLOGGER - * - * @par How GStreamer logging - * - A callback function gst_debug_add_log_function() is registered to receive gstreamer logs. - * - Logs are converted to RDK logs in callback function. - * - RMF element which controls a gst-element shall register element name and corresponding log module using - * void RMF_registerGstElementDbgModule(char *gst_module, char *rmf_module) - * - Callback function uses this information to get module names corresponding to gstreamer logs. - * - * @par RDK Logging architecture - * - * @image html rdk_logger_architecture.jpg - * - * @par RDK Logging Configuration - * @n Default level of logging is ERROR. Logging settings are configured in debug.ini - * @code - * - LOG.RDK. = FATAL ERROR WARNING NOTICE INFO - * - LOG.RDK. = FATAL ERROR WARNING NOTICE INFO DEBUG - * @endcode - * - * @details Default log level entries for each modules are present in the debug.ini - * These entries are read at startup and can be modifiy/add as per the requirement. - * @details Bydefault logs are redirected to /opt/logs/ocapri_log.txt. - * But these can be configure to capture logs for each component in separate files under - * /opt/logs/ by setting configuration parameter SEPARATE.LOGFILE.SUPPORT as TRUE in - * debug.ini - * @details Following logs files generated if SEPARATE.LOGFILE.SUPPORT=TRUE - * - * For POD: pod_log.txt - * - * For CANH Daemon: canh_log.txt - * - * For RMFStreamer: rmfstr_log.txt - * - * @par Logging Levels supported by RDK Logger. - * Code | Description - * -----|------------ - * RDK_LOG_FATAL | Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss), reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss. - * RDK_LOG_ERROR | Any error which is fatal to the operation but not the service (cant open a file, missing data, etc) - * RDK_LOG_WARN | Anything that can potentially cause application oddities, but for which the application automatically recoverring. - * RDK_LOG_NOTICE | Anything that largely superfluous for application-level logging. - * RDK_LOG_INFO | Generally useful information to log (service start/stop, configuration assumptions, etc). - * RDK_LOG_DEBUG | Information that is diagnostically helpful to people more than just developers. - * RDK_LOG_TRACE | Only when it would be "tracing" the code and trying to find one part of a function specifically. - * - * @par How log files are upload to server - * @image html rdk_logupload.jpg - * - * @defgroup RDKLOGGER_DEBUG_API RDK Logger APIs - * Describe the details about RDK debug APIs specifications. - * @ingroup RDKLOGGER - * - * @defgroup RDKLOGGER_UTILS_API RDK Logger Utils APIs - * Describe the details about RDK Logger utils API specifications. - * @ingroup RDKLOGGER - */ - -/** -* @defgroup rdk_logger -* @{ -* @defgroup include -* @{ -**/ - - -#ifndef _RDK_DEBUG_H_ +#ifndef _RDK_DEBUG_H #define _RDK_DEBUG_H_ -#include -#include "rdk_logger_types.h" -#include "rdk_error.h" -#ifdef __cplusplus -extern "C" -{ -#endif - - -/** -* Macros for ease of applications using RDK_LOGGER apis -*/ - -/** - * Define the default location of configuration file location - */ -#define DEBUG_INI_NAME "/etc/debug.ini" - -/** - * Support for overriding debug.ini file location - */ -#ifndef DEBUG_INI_OVERRIDE_PATH -#define DEBUG_INI_OVERRIDE_PATH "/nvram/debug.ini" -#endif - -/** - * Support for Init function - */ -#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ - ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ - : rdk_logger_init(DEBUG_INI_NAME); -/** - * Use RDK_LOG debug message as. - * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) - * @param level Log level of the log message - * @param module Module in which this message belongs to (Use module name same as mentioned in debug.ini) - * @param format Printf style string containing the log message. - */ -#define RDK_LOG rdk_logger_msg_printf -#define RDK_LOG1 rdk_logger_msg_vsprintf - -/** - * Define the max length for the log file capture - */ -#define RDK_LOGGER_EXT_FILENAME_SIZE 32 - -/** - * Define the max length for the log capture path - */ -#define RDK_LOGGER_EXT_LOGDIR_SIZE 32 - -/** - * To allow compatibility of mutiple legacy RDK components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 - */ -#define RDK_LOG_TRACE1 RDK_LOG_TRACE -#define RDK_LOG_TRACE2 RDK_LOG_TRACE -#define RDK_LOG_TRACE3 RDK_LOG_TRACE -#define RDK_LOG_TRACE4 RDK_LOG_TRACE -#define RDK_LOG_TRACE5 RDK_LOG_TRACE -#define RDK_LOG_TRACE6 RDK_LOG_TRACE -#define RDK_LOG_TRACE7 RDK_LOG_TRACE -#define RDK_LOG_TRACE8 RDK_LOG_TRACE -#define RDK_LOG_TRACE9 RDK_LOG_TRACE - -/** - * An access function macro to check logging is enabled or not - */ -#define rdk_dbg_enabled rdk_logger_is_logLevel_enabled - -/** - * @enum rdk_LogLevel - * @brief These values represent the logging 'levels' or 'types', they are each - * independent. - */ -typedef enum -{ - RDK_LOG_FATAL = 0, - RDK_LOG_ERROR, - RDK_LOG_WARN, - RDK_LOG_NOTICE, - RDK_LOG_INFO, - RDK_LOG_DEBUG, - RDK_LOG_TRACE, - RDK_LOG_NONE -} rdk_LogLevel; - -typedef struct rdk_logger_ext_config_t - { - char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; - char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; - long maxSize; - long maxCount; - }rdk_logger_ext_config_t; - -/** - * @brief Initialize the RDK Logger. - * @param debugConfigFile Path to the debug.ini configuration file. - * @return RDK_SUCCESS on success, error code otherwise. - */ -rdk_Error rdk_logger_init(const char* debugConfigFile); - -/** - * @brief Extended initialization for RDK Logger. - * @param config Pointer to rdk_logger_ext_config_t structure. - * @return RDK_SUCCESS on success, error code otherwise. - */ -rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config); - -/** - * @brief Deinitialize the RDK Logger. - * @return RDK_SUCCESS on success, error code otherwise. - */ -rdk_Error rdk_logger_deinit(void); - -/** - * @brief Log a message with printf-style formatting. - * @param level Log level. - * @param module Module name. - * @param format Printf-style format string. - */ -void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...); - -/** - * @brief Log a message using a va_list. - * @param level Log level. - * @param module Module name. - * @param format Printf-style format string. - * @param args va_list of arguments. - */ -void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args); - -/** - * @brief Check if a log level is enabled for a module. - * @param module Module name. - * @param level Log level. - * @return TRUE if enabled, FALSE otherwise. - */ -rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); - -/** - * @brief Enable or disable a log level for a module. - * @param module Module name. - * @param logLevel Log level. - * @param enableLogLvl TRUE to enable, FALSE to disable. - * @return TRUE if successful, FALSE otherwise. - */ -rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); - -/** - * @brief Log a message for onboard logging. - * @param module Module name. - * @param msg Message to log. - */ -void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribute__ ((format (printf, 2, 3))); - -/** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API - -#ifdef __cplusplus -} -#endif +#include "rdk_logger.h" #endif /* _RDK_DEBUG_H_ */ diff --git a/include/rdk_logger.h b/include/rdk_logger.h new file mode 100644 index 0000000..4048c21 --- /dev/null +++ b/include/rdk_logger.h @@ -0,0 +1,293 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/** + * @file rdk_logger.h + * The header file provides RDK Logger APIs. + */ + +/** + * @defgroup RDKLOGGER RDK Logger + * RDK Logger provides common logging capability for all RDK components. + * It is a common logging library which is based on MPEOS logging & uses log4c for + * formatting and supports multiple log levels. + * + * @par RDK Logger Capabilities + * + * - Abstracts logging client from underlying logging utility. + * - Dynamically enables/disables logging level at run time. + * - Provides logging format that complies with the existing OCAP format (e.g. [mod=*, level=*]). + * - Controls log level independently for each component/module. + * - Enables logging globally via single configuration value. + * - Controls initial log level for each component/module from configuration file (debug.ini) at startup. + * - The debug.ini is the main configuration file for RDK Logger and it is intended to be used + * globally in multi-process environment. + * - Prints formatted data to stdout. + * + * @par How to add the RDK logger functionality to the new module? + * @n Include rdk_logger.h header file and make use of RDK_LOG for printing logs. Initialize RDK Logger by + * calling rdk_logger_init() in the respective module/component. Build new module/component by linking + * "librdkloggers.so" along with "liblog4c.so" and "libglib-2.0.so" shared object. + * @code + * Example: -lrdkloggers -L ../opensource/lib -llog4c -lglib-2.0 + * @endcode + * + * @par RDK Logger Usage + * @code + * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) + * @endcode + * - "level" is Log level of the log message (FATAL, ERROR etc). Apart from this there are + * special log levels like ALL, NONE, TRACE, !TRACE are supported. + * - "module" is the Module to which this message belongs to (Use module name same as mentioned in debug.ini) + * - "format" is a printf style string containing the log message. + * + * @par Sample code for Logging: + * For example, add a debug messages for "SI" module + * @code + * RDK_LOG (RDK_LOG_NOTICE, "LOG.RDK.SI","<%s: %s>: Sending PMT_ACQUIRED event\n", PSIMODULE, __FUNCTION__); + * @endcode + * + * @par Sample logging output: + * @code + * 131011-21:21:49.578394 [mod=INBSI, lvl=NOTICE] [tid=4141] : Sending PMT_ACQUIRED event + * @endcode + * + * In this way, user make use of the RDK logger in the respective modules and control the logging levels through configuration file. + * Here, No need to build RDK logger again for the addition of new components/module. + * @ingroup RDKLOGGER + * + * @par RDK Logging architecture + * + * @image html rdk_logger_architecture.jpg + * + * @par RDK Logging Configuration + * @n Default level of logging is WARNING. Logging settings can be overriden by debug.ini + * @code + * - LOG.RDK. = INFO + * - LOG.RDK. = DEBUG + * @endcode + * + * @par Logging Levels supported by RDK Logger. + * Code | Description + * -----|------------ + * RDK_LOG_FATAL | Any error that is forcing a shutdown of the service or application to prevent data loss (or further data loss), reserve these only for the most heinous errors and situations where there is guaranteed to have been data corruption or loss. + * RDK_LOG_ERROR | Any error which is fatal to the operation but not the service (cant open a file, missing data, etc) + * RDK_LOG_WARN | Anything that can potentially cause application oddities, but for which the application automatically recoverring. + * RDK_LOG_NOTICE | Anything that largely superfluous for application-level logging. + * RDK_LOG_INFO | Generally useful information to log (service start/stop, configuration assumptions, etc). + * RDK_LOG_DEBUG | Information that is diagnostically helpful to people more than just developers. + * RDK_LOG_TRACE | Only when it would be "tracing" the code and trying to find one part of a function specifically. + * + * @par How log files are upload to server + * @image html rdk_logupload.jpg + * + * @defgroup RDKLOGGER_LOGGER_API RDK Logger APIs + * Describe the details about RDK Logger APIs specifications. + * @ingroup RDKLOGGER + * + * @defgroup RDKLOGGER_UTILS_API RDK Logger Utils APIs + * Describe the details about RDK Logger utils API specifications. + * @ingroup RDKLOGGER + */ + +/** +* @defgroup rdk_logger +* @{ +* @defgroup include +* @{ +**/ + + +#ifndef _RDK_LOGGER_H_ +#define _RDK_LOGGER_H_ + +#include +#include "rdk_logger_types.h" +#include "rdk_error.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** +* Macros for ease of applications using RDK_LOGGER apis +*/ + +/** + * Define the default location of configuration file location + */ +#define DEBUG_INI_NAME "/etc/debug.ini" + +/** + * Support for overriding debug.ini file location + */ +#ifndef DEBUG_INI_OVERRIDE_PATH +#define DEBUG_INI_OVERRIDE_PATH "/nvram/debug.ini" +#endif + +/** + * Support for Init function + */ +#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ + ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ + : rdk_logger_init(DEBUG_INI_NAME); +/** + * Use RDK_LOG debug message as. + * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) + * @param level Log level of the log message + * @param module Module in which this message belongs to (Use module name same as mentioned in debug.ini) + * @param format Printf style string containing the log message. + */ +#define RDK_LOG rdk_logger_msg_printf +#define RDK_LOG1 rdk_logger_msg_vsprintf +/** + * Define the max length for the log file capture + */ +#define RDK_LOGGER_EXT_FILENAME_SIZE 32 + +/** + * Define the max length for the log capture path + */ +#define RDK_LOGGER_EXT_LOGDIR_SIZE 32 + +/** + * To allow compatibility of mutiple legacy RDK components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 + */ +#define RDK_LOG_TRACE1 RDK_LOG_TRACE +#define RDK_LOG_TRACE2 RDK_LOG_TRACE +#define RDK_LOG_TRACE3 RDK_LOG_TRACE +#define RDK_LOG_TRACE4 RDK_LOG_TRACE +#define RDK_LOG_TRACE5 RDK_LOG_TRACE +#define RDK_LOG_TRACE6 RDK_LOG_TRACE +#define RDK_LOG_TRACE7 RDK_LOG_TRACE +#define RDK_LOG_TRACE8 RDK_LOG_TRACE +#define RDK_LOG_TRACE9 RDK_LOG_TRACE + +/** + * An access function macro to check logging is enabled or not + */ +#define rdk_dbg_enabled rdk_logger_is_logLevel_enabled + +/** + * To allow compatibility of mutiple legacy RDK components using onboard API + */ +#define rdk_log_onboard rdk_logger_log_onboard + +/** + * @enum rdk_LogLevel + * @brief These values represent the logging 'levels' or 'types', they are each + * independent. + */ +typedef enum +{ + RDK_LOG_FATAL = 0, + RDK_LOG_ERROR, + RDK_LOG_WARN, + RDK_LOG_NOTICE, + RDK_LOG_INFO, + RDK_LOG_DEBUG, + RDK_LOG_TRACE, + RDK_LOG_NONE +} rdk_LogLevel; + +typedef struct rdk_logger_ext_config_t + { + char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; + char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; + long maxSize; + long maxCount; + }rdk_logger_ext_config_t; + +/** + * @brief Initialize the RDK Logger. + * @param debugConfigFile Path to the debug.ini configuration file. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_init(const char* debugConfigFile); + +/** + * @brief Extended initialization for RDK Logger. + * @param config Pointer to rdk_logger_ext_config_t structure. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config); + +/** + * @brief Deinitialize the RDK Logger. + * @return RDK_SUCCESS on success, error code otherwise. + */ +rdk_Error rdk_logger_deinit(void); + +/** + * @brief Log a message with printf-style formatting. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + */ +void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); + +/** + * @brief Log a message using a va_list. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + * @param args va_list of arguments. + */ +void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args); + +/** + * @brief Check if a log level is enabled for a module. + * @param module Module name. + * @param level Log level. + * @return TRUE if enabled, FALSE otherwise. + */ +rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); + +/** + * @brief Enable or disable a log level for a module. + * @param module Module name. + * @param logLevel Log level. + * @param enableLogLvl TRUE to enable, FALSE to disable. + * @return TRUE if successful, FALSE otherwise. + */ +rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); + +/** + * @brief Log a message for onboard logging. + * @param module Module name. + * @param msg Message to log. + */ +void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribute__ ((format (printf, 2, 3))); + +/** + * @brief legacy method to Log a message with printf-style formatting; + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + */ +void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); + +/** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API + +#ifdef __cplusplus +} +#endif + +#endif /* _RDK_LOGGER_H_ */ diff --git a/src/include/rdk_utils.h b/include/rdk_utils.h similarity index 100% rename from src/include/rdk_utils.h rename to include/rdk_utils.h diff --git a/src/Makefile.am b/src/Makefile.am index 811b395..feb50a3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,9 +20,7 @@ AM_CPPFLAGS = -pthread -Wall lib_LTLIBRARIES = librdkloggers.la librdkloggers_la_SOURCES = rdk_debug.c rdk_debug_priv.c rdk_dynamic_logger.c rdk_logger_init.c rdk_logger_util.c rdk_logger_milestone.cpp -if IS_ONBOARDLOG_ENABLED librdkloggers_la_SOURCES += rdk_logger_onboard.c -endif librdkloggers_la_CFLAGS = $(LOG4C_CFLAGS) $(GLIB_CFLAGS) $(SYSLOG_HELPER_CFLAGS) $(SYSTEMD_CLFAGS) -I./include -I../include -I${RDK_PROJECT_ROOT_PATH}/opensource/include/log4c -I${RDK_PROJECT_ROOT_PATH}/opensource/include -DDEBUG_CONF_FILE="\"debug.ini\"" librdkloggers_la_LDFLAGS = $(GLIB_LIBS) $(LOG4C_LIBS) $(SYSLOG_HELPER_LDFLAGS) $(SYSTEMD_LDFLAGS) librdkloggers_la_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/include -I$(top_srcdir)/include diff --git a/src/include/rdk_debug_priv.h b/src/include/rdk_debug_priv.h index b2b71c4..57fe31c 100644 --- a/src/include/rdk_debug_priv.h +++ b/src/include/rdk_debug_priv.h @@ -21,7 +21,7 @@ #define _RDK_DBG_PRIV_H #include -#include +#include #include #ifdef __cplusplus diff --git a/src/include/rdk_dynamic_logger.h b/src/include/rdk_dynamic_logger.h index e087e0a..2be2cdd 100644 --- a/src/include/rdk_dynamic_logger.h +++ b/src/include/rdk_dynamic_logger.h @@ -20,7 +20,7 @@ #if !defined(_RDK_DBG_PRIV_DYNLOG_H) #define _RDK_DBG_PRIV_DYNLOG_H -#include +#include void rdk_dyn_log_init(void); void rdk_dyn_log_deinit(void); diff --git a/src/rdk_debug.c b/src/rdk_debug.c index a78d0b0..a33521a 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -30,7 +30,7 @@ **/ -#include +#include #include #include // memset @@ -71,7 +71,23 @@ void rdk_dbg_deinit() */ void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...) { - int num; + va_list args; + + va_start(args, format); + rdk_dbg_priv_log_msg(level, module, format, args); + va_end(args); +} + +/** + * @brief Send a debugging message to the debugging window. It is appended to the log output based + * on configurations set in the environment file. + * + * @param[in] level The debug logging level. + * @param[in] module The name of the module for which this message belongs to, it is mentioned in debug.ini. + * @param[in] format Printf style string containing the log message. + */ +void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, ...) +{ va_list args; va_start(args, format); diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index 0e6ba8a..8430d9a 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -297,6 +297,7 @@ static void printTime(const struct tm *pTm, char *pBuff) ****************************************************************************/ void rdk_dbg_priv_config(void) { + int mod = 1; const char *defaultValue = rdk_logger_envGet("LOG.RDK.DEFAULT"); if (defaultValue && defaultValue[0] != 0) { @@ -334,7 +335,7 @@ void rdk_dbg_priv_config(void) return; } - for (int mod = 1; mod <= global_count; mod++) + for (mod = 1; mod <= global_count; mod++) { const char* modName = rdk_logger_envGetModFromNum(mod); const char* modValue = rdk_logger_envGetValueFromNum(mod); @@ -372,7 +373,7 @@ void rdk_dbg_priv_config(void) /** * @brief Function to check if a specific log level of a module is enabled. * - * @param[in] module The module name or category for for which the log level shall be checked (as mentioned in debug.ini). + * @param[in] module The module name or category for which the log level shall be checked (as mentioned in debug.ini). * @param[in] level The debug logging level. * * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. diff --git a/src/rdk_logger_init.c b/src/rdk_logger_init.c index 8ad825d..fd09f2d 100644 --- a/src/rdk_logger_init.c +++ b/src/rdk_logger_init.c @@ -35,7 +35,7 @@ #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "rdk_error.h" #include "rdk_debug_priv.h" #include "rdk_dynamic_logger.h" diff --git a/src/rdk_logger_onboard.c b/src/rdk_logger_onboard.c index f6ec8ca..ae35294 100644 --- a/src/rdk_logger_onboard.c +++ b/src/rdk_logger_onboard.c @@ -16,7 +16,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifdef FEATURE_SUPPORT_ONBOARD_LOGGING #include #include #include @@ -92,4 +91,3 @@ void rdk_logger_log_onboard(const char *module, const char *msg, ...) } } } -#endif diff --git a/src/rdk_logger_util.c b/src/rdk_logger_util.c index b95a671..1f2e6ac 100644 --- a/src/rdk_logger_util.c +++ b/src/rdk_logger_util.c @@ -28,7 +28,7 @@ /* Header Files */ #include /* Resolve basic type references. */ -#include "rdk_debug.h" /* Resolved RDK_LOG support. */ +#include "rdk_logger.h" /* Resolved RDK_LOG support. */ #include "rdk_error.h" #include "rdk_utils.h" diff --git a/test/rdk_logger_debug_test.c b/test/rdk_logger_debug_test.c index 4dce53b..ac21bff 100644 --- a/test/rdk_logger_debug_test.c +++ b/test/rdk_logger_debug_test.c @@ -19,7 +19,7 @@ #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" int rdk_logger_debug_test() { RDK_LOG(RDK_LOG_FATAL, "LOG.RDK.GFX", diff --git a/test/rdk_logger_test_main.c b/test/rdk_logger_test_main.c index 6e7027a..b0e8649 100644 --- a/test/rdk_logger_test_main.c +++ b/test/rdk_logger_test_main.c @@ -18,7 +18,7 @@ */ #include -#include "rdk_debug.h" +#include "rdk_logger.h" int rdk_logger_debug_test(); diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index f11f652..37b9675 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -21,26 +21,9 @@ project(rdk_logger_gtest) # Find the gtest package find_package(GTest REQUIRED) -include_directories(${RDKLOGGER_SOURCE_PATH}/) -include_directories(${RDKLOGGER_SOURCE_PATH}/include) -include_directories(${RDKLOGGER_SOURCE_PATH}/src/include) -include_directories(${RDKLOGGER_SOURCE_PATH}/cfg) -include_directories(${RDKLOGGER_UNITTEST_DIR}/) - -# Set the path to the gtest installation directory -set(GTEST_ROOT "${RDKLOGGER_UNITTEST_DIR}/googletest/") - -# Add the test executable -#add_executable(unitTestRunner testRunner.cpp) - -# Link the gtest libraries to the test executable -#target_link_libraries(unitTestRunner GTest::GTest GTest::Main) - enable_testing() -link_directories("${RDKLOGGER_SOURCE_PATH}/src/.libs/") -link_directories("${DEP_LIB_PATH}/log4c-1.2.3/install/lib/") -link_directories("${RDKLOGGER_UNITTEST_DIR}/googletest/build/lib/") +link_directories("${DEP_LIB_PATH}/") # Add the test executable add_executable( @@ -51,15 +34,15 @@ add_executable( rdkIsDbgEnabled.cpp main.cpp ) -target_compile_definitions(rdk_logger_gtest PRIVATE GTEST_DEBUG_INI_FILE="${RDKLOGGER_UNITTEST_DIR}/sample_gtest_debug.ini") +target_compile_definitions(rdk_logger_gtest PRIVATE GTEST_DEBUG_INI_FILE="sample_gtest_debug.ini") -install (CODE "execute_process (COMMAND ${CMAKE_COMMAND} -E copy ${RDKLOGGER_UNITTEST_DIR}/Gtest_log4crc ${RDKLOGGER_UNITTEST_DIR}/build/log4crc)") +install (CODE "execute_process (COMMAND ${CMAKE_COMMAND} -E copy Gtest_log4crc ${CMAKE_INSTALL_PREFIX}/log4crc)") if (NOT GTEST_INCLUDE_DIR) - target_link_libraries(rdk_logger_gtest -L${RDKLOGGER_SOURCE_PATH}/src/.libs -lrdkloggers -L${DEP_LIB_PATH}/log4c-1.2.3/install/lib/ -llog4c -l:libgtest.a gcov) + target_link_libraries(rdk_logger_gtest -L${DEP_LIB_PATH} -lrdkloggers -llog4c -l:libgtest.a gcov) else () - target_link_libraries(rdk_logger_gtest -L${RDKLOGGER_SOURCE_PATH}/src/.lib -L${DEP_LIB_PATH}/log4c-1.2.3/install/lib/ rdkloggers log4c gtest gcov) + target_link_libraries(rdk_logger_gtest -L${DEP_LIB_PATH} -lrdkloggers -llog4c gtest gcov) endif() # Link the gtest libraries to the test executable @@ -68,11 +51,7 @@ target_link_libraries( GTest::gtest_main ) -message("RDKLOGGER_SOURCE_PATH ${RDKLOGGER_SOURCE_PATH} RDK_PROJECT_ROOT_PATH ${RDK_PROJECT_ROOT_PATH} RDKLOGGER_UNITTEST_DIR ${RDKLOGGER_UNITTEST_DIR}.") -include_directories(${RDKLOGGER_UNITTEST_DIR}/googletest/googletest/include) -include_directories(${RDKLOGGER_UNITTEST_DIR}/googletest/googletest/src) -include_directories(${RDKLOGGER_SOURCE_PATH}/include) -include_directories(${DEP_LIB_PATH}/log4c-1.2.3/src/log4c) +include_directories(${DEP_LIB_PATH}/../include) include(GoogleTest) gtest_discover_tests(rdk_logger_gtest) find_package(Threads) diff --git a/unittests/main.cpp b/unittests/main.cpp index 8d91a1f..e5973bb 100644 --- a/unittests/main.cpp +++ b/unittests/main.cpp @@ -18,7 +18,7 @@ */ #include "gtest/gtest.h" -char gtestReportPath[] = "xml:/tmp/Gtest_Report/rbus_gtest_report.xml"; +char gtestReportPath[] = "xml:/tmp/Gtest_Report/rdklogger_gtest_report.xml"; GTEST_API_ int main(int argc, char* argv[]) { diff --git a/unittests/rdkIsDbgEnabled.cpp b/unittests/rdkIsDbgEnabled.cpp index 2ebc96b..9befa11 100644 --- a/unittests/rdkIsDbgEnabled.cpp +++ b/unittests/rdkIsDbgEnabled.cpp @@ -22,7 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "gtest_app.h" #if 0 diff --git a/unittests/rdkloggerInit.cpp b/unittests/rdkloggerInit.cpp index 34ed43d..b595f90 100644 --- a/unittests/rdkloggerInit.cpp +++ b/unittests/rdkloggerInit.cpp @@ -22,7 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "gtest_app.h" /*DIABLED some test cases as there's a bug "https://bugzilla.redhat.com/show_bug.cgi?id=1901955" in log4c library, calling log4c_init twice causing segmentation fault, hence keeping rdk_logger_deinit()'s default changes which does not allow calling rdk_logger_init twice*/ diff --git a/unittests/rdkloggerMsgPrintf.cpp b/unittests/rdkloggerMsgPrintf.cpp index 606164f..6471917 100644 --- a/unittests/rdkloggerMsgPrintf.cpp +++ b/unittests/rdkloggerMsgPrintf.cpp @@ -22,7 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "gtest_app.h" TEST(rdkloggerMsgPrintf, logModule_ONLYFATAL_output_to_file) diff --git a/unittests/rdkloggerMsgVsprintf.cpp b/unittests/rdkloggerMsgVsprintf.cpp index 83b6d69..7d53ae9 100644 --- a/unittests/rdkloggerMsgVsprintf.cpp +++ b/unittests/rdkloggerMsgVsprintf.cpp @@ -22,7 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #include "gtest_app.h" void gtest_rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *mod, const char *format, ...) diff --git a/utils/Makefile.am b/utils/Makefile.am index e96182a..098858d 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -21,19 +21,17 @@ bin_PROGRAMS = rdklogctrl rdklogctrl_SOURCES=rdklogctrl.c rdklogctrl_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/include -I./usr/include -rdklogctrl_LDFLAGS = -I./usr/lib +rdklogctrl_LDFLAGS = -L/usr/lib -if IS_MILESTONE_ENABLED bin_PROGRAMS += rdkLogMileStone rdkLogMileStone_SOURCES = rdklogmilestone.c -rdkLogMileStone_LDADD = $(top_builddir)/src/librdkloggers.la +rdkLogMileStone_LDADD = $(top_builddir)/src/librdkloggers.la $(LOG4C_LIBS) rdkLogMileStone_CFLAGS = -I$(top_srcdir)/include -endif +rdkLogMileStone_LDFLAGS = -L/usr/lib -if IS_ONBOARDLOG_ENABLED -bin_PROGRAMS = onboarding_log + +bin_PROGRAMS += onboarding_log onboarding_log_SOURCES = rdk_logger_onboard_main.c -onboarding_log_LDADD = $(top_builddir)/src/librdkloggers.la +onboarding_log_LDADD = $(top_builddir)/src/librdkloggers.la $(LOG4C_LIBS) onboarding_log_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/include -I./usr/include -onboarding_log_LDFLAGS = -I./usr/lib -endif +onboarding_log_LDFLAGS = -L/usr/lib diff --git a/utils/rdk_logger_onboard_main.c b/utils/rdk_logger_onboard_main.c index 49bffaf..40788e3 100644 --- a/utils/rdk_logger_onboard_main.c +++ b/utils/rdk_logger_onboard_main.c @@ -16,11 +16,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifdef FEATURE_SUPPORT_ONBOARD_LOGGING #include #include #include -#include "rdk_debug.h" +#include "rdk_logger.h" #define MAX_BUF_SIZE 1024 @@ -40,4 +39,3 @@ int main( int argc, char **argv) return 0; } -#endif From a46c1ca443d2f83ee1fe1b67a5dd7c3c8dc44e45 Mon Sep 17 00:00:00 2001 From: Karunakaran A Date: Mon, 1 Sep 2025 13:16:24 -0400 Subject: [PATCH 11/37] Release of RDKLogger v2.1.0 Release of RDKLogger v2.1.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29..df4053c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,26 @@ +### Changelog + +All notable changes to this project will be documented in this file. Dates are displayed in UTC. + +Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). + +#### [v2.1.0](https://github.com/rdkcentral/rdk_logger/compare/v2.0.0...v2.1.0) + +- RDKB-60970: RDKLogger OpenSource Migration [`#20`](https://github.com/rdkcentral/rdk_logger/pull/20) + +#### v2.0.0 + +> 5 August 2025 + +- RDKEMW-6709: RDKLogger - Refactoring [`#19`](https://github.com/rdkcentral/rdk_logger/pull/19) +- DELIA-68312: RFC Lock file not deleted after RFC Configuration complete [`#14`](https://github.com/rdkcentral/rdk_logger/pull/14) +- RDKEMW-5034: bcm bb/bbappend analysis for rdk-logger [`#12`](https://github.com/rdkcentral/rdk_logger/pull/12) +- RDKEMW-4586 : Fix for bug Markers not generated [`#11`](https://github.com/rdkcentral/rdk_logger/pull/11) +- RDK-55878 : Converting datapoints to T2 Event [`#10`](https://github.com/rdkcentral/rdk_logger/pull/10) +- RDKEMW-3178: Enable subtec logs with TextTrack activated. [`#9`](https://github.com/rdkcentral/rdk_logger/pull/9) +- RDK-56491: Update debug.ini for nfrtool [`#8`](https://github.com/rdkcentral/rdk_logger/pull/8) +- RDKECMF-178 Fix L1-tests workflow [`#7`](https://github.com/rdkcentral/rdk_logger/pull/7) +- RDK-53334 Integrate RDK logger to Cert Selector library [`#5`](https://github.com/rdkcentral/rdk_logger/pull/5) +- Import of source (develop) [`3accfb1`](https://github.com/rdkcentral/rdk_logger/commit/3accfb141546bc35f25e64d9156c8cbfbf53ba39) +- Remove building cmake from source [`467a8d5`](https://github.com/rdkcentral/rdk_logger/commit/467a8d5d48bb55ead32e4bacd07d1943a7cd1ae1) +- Release of RDKLogger v2.0.0 [`0087a47`](https://github.com/rdkcentral/rdk_logger/commit/0087a47dbc6c28905f7fd4424a43ed1fc8874389) \ No newline at end of file diff --git a/configure.ac b/configure.ac index 146a1f4..b9dcf09 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 2.0.0) +AC_INIT(rdklogger, 2.1.0) AC_CONFIG_SRCDIR([src]) AM_CONFIG_HEADER(cfg/config.h) AC_CONFIG_MACRO_DIR([cfg]) From 59387ab47b05c47b6fe7090838ce932b7b2a9244 Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Tue, 9 Sep 2025 03:36:47 +0530 Subject: [PATCH 12/37] [RDKC-16005]: RDKLogger OpenSource Migration (#21) * Add new API to convert string log_level to type rdk_logLevel * Resolve warnings from code * Update rdk_dynamic_logger.c --------- Signed-off-by: dshett549 Signed-off-by: Karunakaran A --- include/rdk_logger.h | 7 +++++++ src/rdk_debug.c | 19 +++++++++++++++++++ src/rdk_debug_priv.c | 33 --------------------------------- src/rdk_dynamic_logger.c | 5 +++-- src/rdk_logger_init.c | 2 -- src/rdk_logger_util.c | 2 ++ utils/rdklogctrl.c | 25 +------------------------ 7 files changed, 32 insertions(+), 61 deletions(-) diff --git a/include/rdk_logger.h b/include/rdk_logger.h index 4048c21..304646d 100644 --- a/include/rdk_logger.h +++ b/include/rdk_logger.h @@ -284,6 +284,13 @@ void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribut */ void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +/** + * @brief Convert a log level string to rdk_LogLevel enum. + * @param level Log level as string (e.g., "INFO", "DEBUG"). + * @return Corresponding rdk_LogLevel value, or RDK_LOG_NONE if invalid. + */ +rdk_LogLevel rdk_logger_level_from_string(const char* level); + /** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API #ifdef __cplusplus diff --git a/src/rdk_debug.c b/src/rdk_debug.c index a33521a..e6f88bd 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -122,3 +122,22 @@ rdk_logger_Bool rdk_logger_enable_logLevel(const char *pModuleName, rdk_LogLevel return TRUE; } +/** + * @brief Convert a log level string to rdk_LogLevel enum. + * @param level Log level as string (e.g., "INFO", "DEBUG"). + * @return Corresponding rdk_LogLevel value, or RDK_LOG_NONE if invalid. + */ +rdk_LogLevel rdk_logger_level_from_string(const char* level) +{ + if (!level) return RDK_LOG_NONE; + if (strcasecmp(level, "FATAL") == 0) return RDK_LOG_FATAL; + if (strcasecmp(level, "ERROR") == 0) return RDK_LOG_ERROR; + if (strcasecmp(level, "WARNING") == 0) return RDK_LOG_WARN; + if (strcasecmp(level, "WARN") == 0) return RDK_LOG_WARN; + if (strcasecmp(level, "NOTICE") == 0) return RDK_LOG_NOTICE; + if (strcasecmp(level, "INFO") == 0) return RDK_LOG_INFO; + if (strcasecmp(level, "DEBUG") == 0) return RDK_LOG_DEBUG; + if (strcasecmp(level, "TRACE") == 0) return RDK_LOG_TRACE; + if (strcasecmp(level, "NONE") == 0) return RDK_LOG_NONE; + return RDK_LOG_NONE; +} diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index 8430d9a..e805e93 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -116,14 +116,6 @@ static int stream_env_append(log4c_appender_t* appender, const log4c_logging_eve static int stream_env_plus_stdout_append(log4c_appender_t* appender, const log4c_logging_event_t* event); static int stream_env_close(log4c_appender_t * appender); -/* GLOBALS */ - -static rdk_logger_Bool g_initialized = FALSE; - -static const char *errorMsgs[] = -{ "Error: Invalid module name.", "Warning: Ignoring invalid log name(s)." }; - - /** * Initialize Debug API. */ @@ -155,8 +147,6 @@ static const log4c_appender_type_t log4c_appender_type_stream_env_append_plus_st void rdk_dbg_priv_init() { - const char* envVar; - if (initLogger("LOG.RDK")) { fprintf(stderr, "%s -- initLogger failure?!\n", __FUNCTION__); @@ -264,27 +254,6 @@ static int logNameToEnum(const char *name) return -1; } -/** - * Extract a whitespace delimited token from a string. - * - * @param srcStr Pointer to the source string, this will be modified - * to point to the first character after the token extracted. - * - * @param tokBuf This is a string that will be filled with the - * token. Note: this buffer is assumed to be large enough to hold the - * largest possible token. - */ -static void extractToken(const char **srcStr, char *tokBuf) -{ - const char *src = *srcStr; - while (*src && !isspace(*src)) - { - *tokBuf++ = *src++; - } - *tokBuf = '\0'; - *srcStr = src; -} - static void printTime(const struct tm *pTm, char *pBuff) { sprintf(pBuff,"%02d%02d%02d-%02d:%02d:%02d",pTm->tm_year + 1900 - 2000, pTm->tm_mon + 1, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec); @@ -392,8 +361,6 @@ rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args) { - /** Get the category from module name */ - char cat_name[64] = {'\0'}; log4c_category_t* cat = NULL; int prio = 0; diff --git a/src/rdk_dynamic_logger.c b/src/rdk_dynamic_logger.c index c30f5f7..a60f5d2 100644 --- a/src/rdk_dynamic_logger.c +++ b/src/rdk_dynamic_logger.c @@ -104,7 +104,8 @@ void rdk_dyn_log_process_pending_request() char buf[128] = {0}; struct sockaddr_in sender_addr; struct timeval tv; - int numbytes, addr_len, ret, i = 0; + int numbytes, ret; + socklen_t addr_len; fd_set rfds; if(-1 == g_dl_socket) @@ -141,7 +142,7 @@ void rdk_dyn_log_process_pending_request() */ if((0 == strcmp("127.0.0.1",inet_ntoa(sender_addr.sin_addr))) && (numbytes == buf[4]+DL_SIGNATURE_LEN+1)) { - rdk_dyn_log_validate_component_name(buf); + rdk_dyn_log_validate_component_name((const unsigned char *)buf); } } } diff --git a/src/rdk_logger_init.c b/src/rdk_logger_init.c index fd09f2d..87358a6 100644 --- a/src/rdk_logger_init.c +++ b/src/rdk_logger_init.c @@ -57,8 +57,6 @@ static int isLogInited = 0; rdk_Error rdk_logger_init(const char* debugConfigFile) { rdk_Error ret; - struct stat st; - char buf[BUF_LEN] = {'\0'}; if (0 == isLogInited) { diff --git a/src/rdk_logger_util.c b/src/rdk_logger_util.c index 1f2e6ac..5727f62 100644 --- a/src/rdk_logger_util.c +++ b/src/rdk_logger_util.c @@ -347,6 +347,8 @@ char* rdk_loglevelToString(rdk_LogLevel log_level, rdk_logger_Bool isLogEnabled) return (isLogEnabled) ? "DEBUG":"!DEBUG"; case RDK_LOG_TRACE: return (isLogEnabled) ? "TRACE":"!TRACE"; + case RDK_LOG_NONE: + return "NONE"; } return NULL; diff --git a/utils/rdklogctrl.c b/utils/rdklogctrl.c index 57ec35a..66f877e 100644 --- a/utils/rdklogctrl.c +++ b/utils/rdklogctrl.c @@ -61,33 +61,10 @@ static int validate_loglevel(const char* level) return -1; } -static int validate_module_name(const char *name) -{ - FILE *fp = NULL; - char ch; - char comp_name[128] = {0}; - int ret = -1; - - fp = fopen("/etc/debug.ini","r"); - if(NULL == fp) - return ret; - - do { - ch = fscanf(fp, "%s", comp_name); - if(strstr(comp_name,name)) { - ret = 0; - break; - } - } while(ch == 1); - - fclose(fp); - return ret; -} - int main(int argc, char *argv[]) { struct sockaddr_in dest_addr; - int i, sockfd, numbytes, addr_len, app_len, comp_len, optval = 1; + int i, sockfd, numbytes, app_len, comp_len, optval = 1; int level = -1; unsigned char buf[128] = {0}; From f6df9f400aae062ccb75d5c1ced7a50642589d79 Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Tue, 9 Sep 2025 03:36:47 +0530 Subject: [PATCH 13/37] [RDKC-16005]: RDKLogger OpenSource Migration (#21) * Add new API to convert string log_level to type rdk_logLevel * Resolve warnings from code * Update rdk_dynamic_logger.c --------- Signed-off-by: dshett549 Signed-off-by: Karunakaran A --- include/rdk_logger.h | 7 +++++++ src/rdk_debug.c | 19 +++++++++++++++++++ src/rdk_debug_priv.c | 33 --------------------------------- src/rdk_dynamic_logger.c | 5 +++-- src/rdk_logger_init.c | 2 -- src/rdk_logger_util.c | 2 ++ utils/rdklogctrl.c | 25 +------------------------ 7 files changed, 32 insertions(+), 61 deletions(-) diff --git a/include/rdk_logger.h b/include/rdk_logger.h index 4048c21..304646d 100644 --- a/include/rdk_logger.h +++ b/include/rdk_logger.h @@ -284,6 +284,13 @@ void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribut */ void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +/** + * @brief Convert a log level string to rdk_LogLevel enum. + * @param level Log level as string (e.g., "INFO", "DEBUG"). + * @return Corresponding rdk_LogLevel value, or RDK_LOG_NONE if invalid. + */ +rdk_LogLevel rdk_logger_level_from_string(const char* level); + /** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API #ifdef __cplusplus diff --git a/src/rdk_debug.c b/src/rdk_debug.c index a33521a..e6f88bd 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -122,3 +122,22 @@ rdk_logger_Bool rdk_logger_enable_logLevel(const char *pModuleName, rdk_LogLevel return TRUE; } +/** + * @brief Convert a log level string to rdk_LogLevel enum. + * @param level Log level as string (e.g., "INFO", "DEBUG"). + * @return Corresponding rdk_LogLevel value, or RDK_LOG_NONE if invalid. + */ +rdk_LogLevel rdk_logger_level_from_string(const char* level) +{ + if (!level) return RDK_LOG_NONE; + if (strcasecmp(level, "FATAL") == 0) return RDK_LOG_FATAL; + if (strcasecmp(level, "ERROR") == 0) return RDK_LOG_ERROR; + if (strcasecmp(level, "WARNING") == 0) return RDK_LOG_WARN; + if (strcasecmp(level, "WARN") == 0) return RDK_LOG_WARN; + if (strcasecmp(level, "NOTICE") == 0) return RDK_LOG_NOTICE; + if (strcasecmp(level, "INFO") == 0) return RDK_LOG_INFO; + if (strcasecmp(level, "DEBUG") == 0) return RDK_LOG_DEBUG; + if (strcasecmp(level, "TRACE") == 0) return RDK_LOG_TRACE; + if (strcasecmp(level, "NONE") == 0) return RDK_LOG_NONE; + return RDK_LOG_NONE; +} diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index 8430d9a..e805e93 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -116,14 +116,6 @@ static int stream_env_append(log4c_appender_t* appender, const log4c_logging_eve static int stream_env_plus_stdout_append(log4c_appender_t* appender, const log4c_logging_event_t* event); static int stream_env_close(log4c_appender_t * appender); -/* GLOBALS */ - -static rdk_logger_Bool g_initialized = FALSE; - -static const char *errorMsgs[] = -{ "Error: Invalid module name.", "Warning: Ignoring invalid log name(s)." }; - - /** * Initialize Debug API. */ @@ -155,8 +147,6 @@ static const log4c_appender_type_t log4c_appender_type_stream_env_append_plus_st void rdk_dbg_priv_init() { - const char* envVar; - if (initLogger("LOG.RDK")) { fprintf(stderr, "%s -- initLogger failure?!\n", __FUNCTION__); @@ -264,27 +254,6 @@ static int logNameToEnum(const char *name) return -1; } -/** - * Extract a whitespace delimited token from a string. - * - * @param srcStr Pointer to the source string, this will be modified - * to point to the first character after the token extracted. - * - * @param tokBuf This is a string that will be filled with the - * token. Note: this buffer is assumed to be large enough to hold the - * largest possible token. - */ -static void extractToken(const char **srcStr, char *tokBuf) -{ - const char *src = *srcStr; - while (*src && !isspace(*src)) - { - *tokBuf++ = *src++; - } - *tokBuf = '\0'; - *srcStr = src; -} - static void printTime(const struct tm *pTm, char *pBuff) { sprintf(pBuff,"%02d%02d%02d-%02d:%02d:%02d",pTm->tm_year + 1900 - 2000, pTm->tm_mon + 1, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec); @@ -392,8 +361,6 @@ rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args) { - /** Get the category from module name */ - char cat_name[64] = {'\0'}; log4c_category_t* cat = NULL; int prio = 0; diff --git a/src/rdk_dynamic_logger.c b/src/rdk_dynamic_logger.c index c30f5f7..a60f5d2 100644 --- a/src/rdk_dynamic_logger.c +++ b/src/rdk_dynamic_logger.c @@ -104,7 +104,8 @@ void rdk_dyn_log_process_pending_request() char buf[128] = {0}; struct sockaddr_in sender_addr; struct timeval tv; - int numbytes, addr_len, ret, i = 0; + int numbytes, ret; + socklen_t addr_len; fd_set rfds; if(-1 == g_dl_socket) @@ -141,7 +142,7 @@ void rdk_dyn_log_process_pending_request() */ if((0 == strcmp("127.0.0.1",inet_ntoa(sender_addr.sin_addr))) && (numbytes == buf[4]+DL_SIGNATURE_LEN+1)) { - rdk_dyn_log_validate_component_name(buf); + rdk_dyn_log_validate_component_name((const unsigned char *)buf); } } } diff --git a/src/rdk_logger_init.c b/src/rdk_logger_init.c index fd09f2d..87358a6 100644 --- a/src/rdk_logger_init.c +++ b/src/rdk_logger_init.c @@ -57,8 +57,6 @@ static int isLogInited = 0; rdk_Error rdk_logger_init(const char* debugConfigFile) { rdk_Error ret; - struct stat st; - char buf[BUF_LEN] = {'\0'}; if (0 == isLogInited) { diff --git a/src/rdk_logger_util.c b/src/rdk_logger_util.c index 1f2e6ac..5727f62 100644 --- a/src/rdk_logger_util.c +++ b/src/rdk_logger_util.c @@ -347,6 +347,8 @@ char* rdk_loglevelToString(rdk_LogLevel log_level, rdk_logger_Bool isLogEnabled) return (isLogEnabled) ? "DEBUG":"!DEBUG"; case RDK_LOG_TRACE: return (isLogEnabled) ? "TRACE":"!TRACE"; + case RDK_LOG_NONE: + return "NONE"; } return NULL; diff --git a/utils/rdklogctrl.c b/utils/rdklogctrl.c index 57ec35a..66f877e 100644 --- a/utils/rdklogctrl.c +++ b/utils/rdklogctrl.c @@ -61,33 +61,10 @@ static int validate_loglevel(const char* level) return -1; } -static int validate_module_name(const char *name) -{ - FILE *fp = NULL; - char ch; - char comp_name[128] = {0}; - int ret = -1; - - fp = fopen("/etc/debug.ini","r"); - if(NULL == fp) - return ret; - - do { - ch = fscanf(fp, "%s", comp_name); - if(strstr(comp_name,name)) { - ret = 0; - break; - } - } while(ch == 1); - - fclose(fp); - return ret; -} - int main(int argc, char *argv[]) { struct sockaddr_in dest_addr; - int i, sockfd, numbytes, addr_len, app_len, comp_len, optval = 1; + int i, sockfd, numbytes, app_len, comp_len, optval = 1; int level = -1; unsigned char buf[128] = {0}; From 28d277ae00b0f6fdaae1e8c263706efed9651087 Mon Sep 17 00:00:00 2001 From: kamirt573_comcast Date: Mon, 8 Sep 2025 23:39:27 +0000 Subject: [PATCH 14/37] Release of RDKLogger v2.2.0 Release of v2.2.0 Signed-off-by: kamirt573_comcast --- CHANGELOG.md | 9 ++++++++- configure.ac | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index df4053c..cfbabf0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,16 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v2.2.0](https://github.com/rdkcentral/rdk_logger/compare/v2.1.0...v2.2.0) + +- [RDKC-16005]: RDKLogger OpenSource Migration [`#21`](https://github.com/rdkcentral/rdk_logger/pull/21) + #### [v2.1.0](https://github.com/rdkcentral/rdk_logger/compare/v2.0.0...v2.1.0) +> 1 September 2025 + - RDKB-60970: RDKLogger OpenSource Migration [`#20`](https://github.com/rdkcentral/rdk_logger/pull/20) +- Release of RDKLogger v2.1.0 [`a46c1ca`](https://github.com/rdkcentral/rdk_logger/commit/a46c1ca443d2f83ee1fe1b67a5dd7c3c8dc44e45) #### v2.0.0 @@ -23,4 +30,4 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - RDK-53334 Integrate RDK logger to Cert Selector library [`#5`](https://github.com/rdkcentral/rdk_logger/pull/5) - Import of source (develop) [`3accfb1`](https://github.com/rdkcentral/rdk_logger/commit/3accfb141546bc35f25e64d9156c8cbfbf53ba39) - Remove building cmake from source [`467a8d5`](https://github.com/rdkcentral/rdk_logger/commit/467a8d5d48bb55ead32e4bacd07d1943a7cd1ae1) -- Release of RDKLogger v2.0.0 [`0087a47`](https://github.com/rdkcentral/rdk_logger/commit/0087a47dbc6c28905f7fd4424a43ed1fc8874389) \ No newline at end of file +- Release of RDKLogger v2.0.0 [`0087a47`](https://github.com/rdkcentral/rdk_logger/commit/0087a47dbc6c28905f7fd4424a43ed1fc8874389) diff --git a/configure.ac b/configure.ac index b9dcf09..2ce7b77 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 2.1.0) +AC_INIT(rdklogger, 2.2.0) AC_CONFIG_SRCDIR([src]) AM_CONFIG_HEADER(cfg/config.h) AC_CONFIG_MACRO_DIR([cfg]) From 5303296d8ac21d748325ac1d7c6eefdf34213c3c Mon Sep 17 00:00:00 2001 From: kamirt573_comcast Date: Mon, 8 Sep 2025 23:39:27 +0000 Subject: [PATCH 15/37] Release of RDKLogger v2.2.0 Release of v2.2.0 Signed-off-by: kamirt573_comcast --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ configure.ac | 2 +- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29..d3da6d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,33 @@ +### Changelog + +All notable changes to this project will be documented in this file. Dates are displayed in UTC. + +Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). + +#### [v2.2.0](https://github.com/rdkcentral/rdk_logger/compare/v2.1.0...v2.2.0) + +- [RDKC-16005]: RDKLogger OpenSource Migration [`#21`](https://github.com/rdkcentral/rdk_logger/pull/21) + +#### [v2.1.0](https://github.com/rdkcentral/rdk_logger/compare/v2.0.0...v2.1.0) + +> 1 September 2025 + +- RDKB-60970: RDKLogger OpenSource Migration [`#20`](https://github.com/rdkcentral/rdk_logger/pull/20) +- Release of RDKLogger v2.1.0 [`a46c1ca`](https://github.com/rdkcentral/rdk_logger/commit/a46c1ca443d2f83ee1fe1b67a5dd7c3c8dc44e45) + +#### v2.0.0 + +> 5 August 2025 + +- RDKEMW-6709: RDKLogger - Refactoring [`#19`](https://github.com/rdkcentral/rdk_logger/pull/19) +- DELIA-68312: RFC Lock file not deleted after RFC Configuration complete [`#14`](https://github.com/rdkcentral/rdk_logger/pull/14) +- RDKEMW-5034: bcm bb/bbappend analysis for rdk-logger [`#12`](https://github.com/rdkcentral/rdk_logger/pull/12) +- RDKEMW-4586 : Fix for bug Markers not generated [`#11`](https://github.com/rdkcentral/rdk_logger/pull/11) +- RDK-55878 : Converting datapoints to T2 Event [`#10`](https://github.com/rdkcentral/rdk_logger/pull/10) +- RDKEMW-3178: Enable subtec logs with TextTrack activated. [`#9`](https://github.com/rdkcentral/rdk_logger/pull/9) +- RDK-56491: Update debug.ini for nfrtool [`#8`](https://github.com/rdkcentral/rdk_logger/pull/8) +- RDKECMF-178 Fix L1-tests workflow [`#7`](https://github.com/rdkcentral/rdk_logger/pull/7) +- RDK-53334 Integrate RDK logger to Cert Selector library [`#5`](https://github.com/rdkcentral/rdk_logger/pull/5) +- Import of source (develop) [`3accfb1`](https://github.com/rdkcentral/rdk_logger/commit/3accfb141546bc35f25e64d9156c8cbfbf53ba39) +- Remove building cmake from source [`467a8d5`](https://github.com/rdkcentral/rdk_logger/commit/467a8d5d48bb55ead32e4bacd07d1943a7cd1ae1) +- Release of RDKLogger v2.0.0 [`0087a47`](https://github.com/rdkcentral/rdk_logger/commit/0087a47dbc6c28905f7fd4424a43ed1fc8874389) \ No newline at end of file diff --git a/configure.ac b/configure.ac index b9dcf09..2ce7b77 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 2.1.0) +AC_INIT(rdklogger, 2.2.0) AC_CONFIG_SRCDIR([src]) AM_CONFIG_HEADER(cfg/config.h) AC_CONFIG_MACRO_DIR([cfg]) From a835dd3730fcebd4c767df6664dc72c8da6216e5 Mon Sep 17 00:00:00 2001 From: Karunakaran A <48997923+karuna2git@users.noreply.github.com> Date: Tue, 23 Sep 2025 12:25:27 -0400 Subject: [PATCH 16/37] RDKB-61752 : Add Legacy Function for Backward Compatibility (#23) Reason for change: Add rdk_dbg_* APIs for Backward Compatibility Test Procedure: Verify WiFi Motion Risks: Low Signed-off-by: dshett549 DEEPTHICHANDRASHEKAR_SHETTY@comcast.com Co-authored-by: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> --- include/rdk_logger.h | 9 +++++++++ src/rdk_debug.c | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/include/rdk_logger.h b/include/rdk_logger.h index 304646d..a17a496 100644 --- a/include/rdk_logger.h +++ b/include/rdk_logger.h @@ -284,6 +284,15 @@ void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribut */ void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +/** + * @brief legacy method to Log a message using a va_list. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + * @param args va_list of arguments. + */ +void rdk_dbg_MsgRaw1(rdk_LogLevel level, const char *module, const char *format, va_list args); + /** * @brief Convert a log level string to rdk_LogLevel enum. * @param level Log level as string (e.g., "INFO", "DEBUG"). diff --git a/src/rdk_debug.c b/src/rdk_debug.c index e6f88bd..b4903f0 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -100,6 +100,11 @@ void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char rdk_dbg_priv_log_msg(level, module, format, args); } +void rdk_dbg_MsgRaw1(rdk_LogLevel level, const char *module, const char *format, va_list args) +{ + rdk_dbg_priv_log_msg(level, module, format, args); +} + /** * @brief Function to sets a specific log level of a module. * From 58611647710fe95e5f043dc1d6d1d4bc99c49846 Mon Sep 17 00:00:00 2001 From: Karunakaran A <48997923+karuna2git@users.noreply.github.com> Date: Tue, 23 Sep 2025 14:15:41 -0400 Subject: [PATCH 17/37] Update Documentation for RDKLogger (#24) * Updated the documentation Signed-off-by: Karunakaran A --- README.md | 129 +++ doc/rdklogger-doxygen.cfg | 1799 ------------------------------------- docs/API_DOCUMENTATION.md | 765 ++++++++++++++++ docs/MIGRATION_GUIDE.md | 363 ++++++++ docs/QUICK_REFERENCE.md | 336 +++++++ docs/TROUBLESHOOTING.md | 514 +++++++++++ include/rdk_logger.h | 7 - 7 files changed, 2107 insertions(+), 1806 deletions(-) delete mode 100644 doc/rdklogger-doxygen.cfg create mode 100644 docs/API_DOCUMENTATION.md create mode 100644 docs/MIGRATION_GUIDE.md create mode 100644 docs/QUICK_REFERENCE.md create mode 100644 docs/TROUBLESHOOTING.md diff --git a/README.md b/README.md index 43ab6ec..704e3ee 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,132 @@ LOG.RDK.BAR=NONE ## Runtime Control Use the `rdklogctrl` utility to change log levels for modules at run time. + +```bash +# Set log level for a module +rdklogctrl + +# Examples +rdklogctrl myapp LOG.RDK.NETWORK DEBUG +rdklogctrl receiver LOG.RDK.AUDIO INFO + +# Available levels: FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE, NONE +``` + +## Quick Start + +### 1. Include Headers +```c +#include "rdk_logger.h" +``` + +### 2. Initialize and Use +```c +int main() { + // Initialize logger + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Failed to initialize RDK Logger\n"); + return -1; + } + + // Log messages + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Application started\n"); + RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.MYAPP", "Error: %s\n", strerror(errno)); + + // Cleanup + rdk_logger_deinit(); + return 0; +} +``` + +### 3. Build and Link +```bash +gcc myapp.c -lrdkloggers -llog4c -lglib-2.0 +``` + +## 📚 Complete Documentation + +This repository includes comprehensive documentation for all aspects of RDK Logger: + +### 📖 [API Documentation](docs/API_DOCUMENTATION.md) +**Complete developer reference** +- Detailed API function documentation with parameters and return values +- Architecture overview and capabilities +- Configuration system and debug.ini format +- Runtime control mechanisms and utilities +- Performance optimization and best practices +- Complete real-world examples and usage patterns + +### ⚡ [Quick Reference](docs/QUICK_REFERENCE.md) +**Essential information for daily use** +- Core function syntax and common patterns +- Log level hierarchy and usage guidelines +- Configuration snippets and examples +- Runtime control commands (rdklogctrl) +- Build system integration examples +- Debugging tips and test programs + +### 🔄 [Migration Guide](docs/MIGRATION_GUIDE.md) +**Transitioning from other logging systems** +- Step-by-step migration from printf/fprintf, syslog, and custom logging +- Log level mapping between different systems +- Configuration conversion techniques +- Common migration pitfalls and solutions +- Validation scripts and testing approaches + +### 🛠️ [Troubleshooting Guide](docs/TROUBLESHOOTING.md) +**Solutions for common issues** +- Initialization failures and configuration problems +- Missing log output debugging +- Runtime control issues +- Performance and memory problems +- Multi-threading complications +- Build and linking solutions + +## 🚀 Getting Started Paths + +### For New Users +1. **Read** the [Quick Start](#quick-start) section above +2. **Study** [API Documentation](docs/API_DOCUMENTATION.md) for comprehensive understanding +3. **Reference** [Quick Reference](docs/QUICK_REFERENCE.md) for daily syntax needs + +### For Migrating from Other Systems +1. **Identify** your current logging system in [Migration Guide](docs/MIGRATION_GUIDE.md) +2. **Follow** the step-by-step migration process +3. **Validate** using provided migration scripts and tests + +### For Troubleshooting +1. **Check** [Troubleshooting Guide](docs/TROUBLESHOOTING.md) for your specific issue +2. **Use** debugging techniques and tools provided +3. **Reference** [Quick Reference](docs/QUICK_REFERENCE.md) for correct syntax + +## Log Levels + +| Level | When to Use | +|-------|-------------| +| **FATAL** | System crash, unusable | +| **ERROR** | Operation failures | +| **WARN** | Potential problems | +| **NOTICE** | Important events | +| **INFO** | General information | +| **DEBUG** | Debugging details | +| **TRACE** | Function tracing | + +## Build Dependencies + +- **liblog4c-dev** - Log4C development headers +- **libglib2.0-dev** - GLib development headers +- **autotools** - For building from source + +## Repository Structure + +``` +rdk_logger/ +├── include/ # Header files (rdk_logger.h, etc.) +├── src/ # Source files +├── utils/ # Utility programs (rdklogctrl) +├── test/ # Test programs +├── unittests/ # Unit tests +├── debug.ini.sample # Example configuration +└── docs/ # Comprehensive documentation +``` diff --git a/doc/rdklogger-doxygen.cfg b/doc/rdklogger-doxygen.cfg deleted file mode 100644 index 45f1d0e..0000000 --- a/doc/rdklogger-doxygen.cfg +++ /dev/null @@ -1,1799 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -# Doxyfile 1.7.6.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. - -PROJECT_NAME = "My Project" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = ./doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -SYMBOL_CACHE_SIZE = 0 - -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = ./include/rdk_logger.h - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# style sheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. - -MATHJAX_EXTENSIONS = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to -# set the path where dot can find it. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible in IE 9+ (other browsers do not have this requirement). - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible. Older versions of IE do not have SVG support. - -INTERACTIVE_SVG = NO - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/docs/API_DOCUMENTATION.md b/docs/API_DOCUMENTATION.md new file mode 100644 index 0000000..3b3368e --- /dev/null +++ b/docs/API_DOCUMENTATION.md @@ -0,0 +1,765 @@ +# RDK Logger API Documentation + +## Table of Contents +1. [Overview](#overview) +2. [Architecture](#architecture) +3. [Installation & Build](#installation--build) +4. [Quick Start](#quick-start) +5. [Core APIs](#core-apis) +6. [Configuration](#configuration) +7. [Runtime Control](#runtime-control) +8. [Log Levels](#log-levels) +9. [Utilities](#utilities) +10. [Examples](#examples) +11. [Error Handling](#error-handling) +12. [Best Practices](#best-practices) + +## Overview + +RDK Logger is a comprehensive logging framework designed for RDK (Reference Design Kit) components. It provides: + +- **Centralized Configuration**: Single `debug.ini` file for all components +- **Runtime Control**: Dynamic log level changes without restart +- **Multi-level Logging**: Support for FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE +- **Module-specific Control**: Independent log levels per component/module +- **Performance Optimized**: Minimal overhead when logging is disabled +- **Thread-safe**: Safe for multi-threaded applications + +## Architecture + +``` +┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ +│ Application │───▶│ RDK Logger │───▶│ Log Output │ +│ │ │ │ │ (stdout/file) │ +└─────────────────┘ └──────────────────┘ └─────────────────┘ + │ + ▼ + ┌──────────────────┐ + │ debug.ini │ + │ Configuration │ + └──────────────────┘ +``` + +The RDK Logger sits between your application and the actual log output, providing filtering, formatting, and runtime control capabilities. + +## Installation & Build + +### Prerequisites +- `liblog4c` - Log4C logging library +- `libglib-2.0` - GLib library +- `autotools` - For building from source + +### Build Instructions +```bash +# Configure and build +./configure +make + +# Install +sudo make install +``` + +### Linking in Your Project +```bash +# Compile flags +gcc -o myapp myapp.c -lrdkloggers -llog4c -lglib-2.0 +``` + +## Quick Start + +### 1. Include Headers +```c +#include "rdk_logger.h" +``` + +### 2. Initialize Logger +```c +int main() { + // Initialize with default config file (/etc/debug.ini) + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Failed to initialize RDK Logger\n"); + return -1; + } + + // Your application code here + + // Clean up + rdk_logger_deinit(); + return 0; +} +``` + +### 3. Log Messages +```c +// Basic logging +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Application started successfully\n"); + +// Formatted logging +int port = 8080; +RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.MYAPP", "Server listening on port %d\n", port); + +// Error logging +RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.MYAPP", "Failed to connect to database: %s\n", strerror(errno)); +``` + +## Core APIs + +### Initialization Functions + +#### `rdk_logger_init()` +```c +rdk_Error rdk_logger_init(const char* debugConfigFile); +``` +**Purpose**: Initialize the RDK Logger with a specific configuration file. + +**Parameters**: +- `debugConfigFile`: Path to the debug.ini configuration file + +**Returns**: `RDK_SUCCESS` on success, error code otherwise + +**Example**: +```c +rdk_Error ret = rdk_logger_init("/etc/debug.ini"); +if (ret != RDK_SUCCESS) { + printf("Logger initialization failed\n"); +} +``` + +#### `rdk_logger_ext_init()` +```c +rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config); +``` +**Purpose**: Extended initialization with custom log file configuration. + +**Parameters**: +- `config`: Pointer to extended configuration structure + +**Configuration Structure**: +```c +typedef struct rdk_logger_ext_config_t { + char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; // Log file name + char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; // Log directory path + long maxSize; // Max file size in bytes + long maxCount; // Max number of log files +} rdk_logger_ext_config_t; +``` + +**Example**: +```c +rdk_logger_ext_config_t config = { + .fileName = "myapp.log", + .logdir = "/var/log/", + .maxSize = 1024 * 1024, // 1MB + .maxCount = 5 // Keep 5 log files +}; +rdk_logger_ext_init(&config); +``` + +#### `rdk_logger_deinit()` +```c +rdk_Error rdk_logger_deinit(void); +``` +**Purpose**: Clean up and deinitialize the logger. + +**Returns**: `RDK_SUCCESS` on success + +### Logging Functions + +#### `RDK_LOG` Macro +```c +#define RDK_LOG rdk_logger_msg_printf +``` +**Purpose**: Primary logging macro for formatted messages. + +**Syntax**: +```c +RDK_LOG(level, module, format, ...); +``` + +**Parameters**: +- `level`: Log level (see [Log Levels](#log-levels)) +- `module`: Module name string (should match debug.ini entries) +- `format`: Printf-style format string +- `...`: Variable arguments for format string + +#### `rdk_logger_msg_printf()` +```c +void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...); +``` +**Purpose**: Core logging function with printf-style formatting. + +**Example**: +```c +rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.NETWORK", + "Connection established to %s:%d\n", hostname, port); +``` + +#### `rdk_logger_msg_vsprintf()` +```c +void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args); +``` +**Purpose**: Logging function that accepts a `va_list` for wrapper functions. + +**Example**: +```c +void my_log_wrapper(rdk_LogLevel level, const char *module, const char *format, ...) { + va_list args; + va_start(args, format); + rdk_logger_msg_vsprintf(level, module, format, args); + va_end(args); +} +``` + +### Query and Control Functions + +#### `rdk_logger_is_logLevel_enabled()` +```c +rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); +``` +**Purpose**: Check if a specific log level is enabled for a module. + +**Returns**: `TRUE` if enabled, `FALSE` otherwise + +**Example**: +```c +if (rdk_logger_is_logLevel_enabled("LOG.RDK.MYAPP", RDK_LOG_DEBUG)) { + // Expensive debug computation only if debug logging is enabled + char *debug_info = generate_debug_info(); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.MYAPP", "Debug info: %s\n", debug_info); + free(debug_info); +} +``` + +#### `rdk_logger_enable_logLevel()` +```c +rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); +``` +**Purpose**: Dynamically enable or disable a log level for a module at runtime. + +**Parameters**: +- `module`: Module name +- `logLevel`: Log level to modify +- `enableLogLvl`: `TRUE` to enable, `FALSE` to disable + +**Returns**: `TRUE` if successful + +**Example**: +```c +// Enable debug logging temporarily +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, TRUE); + +// ... debug operations ... + +// Disable debug logging +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, FALSE); +``` + +### Utility Functions + +#### `rdk_logger_level_from_string()` +```c +rdk_LogLevel rdk_logger_level_from_string(const char* level); +``` +**Purpose**: Convert string representation to log level enum. + +**Parameters**: +- `level`: String like "INFO", "DEBUG", "ERROR" + +**Returns**: Corresponding `rdk_LogLevel` value, or `RDK_LOG_NONE` if invalid + +**Example**: +```c +rdk_LogLevel level = rdk_logger_level_from_string("DEBUG"); +if (level != RDK_LOG_NONE) { + rdk_logger_enable_logLevel("LOG.RDK.MYAPP", level, TRUE); +} +``` + +#### `rdk_logger_log_onboard()` +```c +void rdk_logger_log_onboard(const char *module, const char *msg, ...); +``` +**Purpose**: Special logging function for onboard/milestone logging. + +**Example**: +```c +rdk_logger_log_onboard("LOG.RDK.SYSTEM", "System initialization completed"); +``` + +## Configuration + +### debug.ini File Format + +The `debug.ini` file controls logging behavior for all modules: + +```ini +########################################################################## +# RDK Logger Configuration +# Format: LOG.RDK.= +########################################################################## + +# Default log level for all modules +LOG.RDK.DEFAULT=WARNING + +# Module-specific log levels +LOG.RDK.NETWORK=DEBUG # Network module: debug and above +LOG.RDK.DATABASE=INFO # Database module: info and above +LOG.RDK.SECURITY=ERROR # Security module: error and above +LOG.RDK.TESTMODULE=NONE # Test module: no logging +``` + +### Configuration Locations + +1. **Primary**: `/etc/debug.ini` +2. **Override**: `/nvram/debug.ini` (takes precedence if exists) +3. **Custom**: Specified in `rdk_logger_init()` call + +### Module Naming Convention + +- **RDK Components**: Must start with `LOG.RDK.` +- **Example**: `LOG.RDK.NETWORK`, `LOG.RDK.AUDIO`, `LOG.RDK.VIDEO` +- **Default Module**: `LOG.RDK.DEFAULT` sets the fallback level + +## Runtime Control + +### Using rdklogctrl Utility + +The `rdklogctrl` command-line utility allows runtime modification of log levels: + +```bash +# Set log level for a module +rdklogctrl + +# Examples +rdklogctrl myapp LOG.RDK.NETWORK DEBUG +rdklogctrl receiver LOG.RDK.AUDIO INFO +rdklogctrl player LOG.RDK.VIDEO ERROR + +# Disable specific log level (using ~ prefix) +rdklogctrl myapp LOG.RDK.NETWORK ~DEBUG +``` + +**Parameters**: +- `app_name`: Process name as shown by `ps` command +- `module_name`: Module name (must match debug.ini format) +- `log_level`: FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE, NONE + +### Programmatic Runtime Control + +```c +// Enable debug logging at runtime +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, TRUE); + +// Check if logging is enabled before expensive operations +if (rdk_dbg_enabled("LOG.RDK.MYAPP", RDK_LOG_TRACE)) { + generate_detailed_trace(); +} +``` + +## Log Levels + +### Available Log Levels + +| Level | Value | Description | Use Case | +|-------|-------|-------------|----------| +| `RDK_LOG_FATAL` | 0 | System unusable | Critical failures, system crash | +| `RDK_LOG_ERROR` | 1 | Error conditions | Errors that affect functionality | +| `RDK_LOG_WARN` | 2 | Warning conditions | Potential problems, degraded performance | +| `RDK_LOG_NOTICE` | 3 | Normal significant condition | Important normal events | +| `RDK_LOG_INFO` | 4 | Informational messages | General application flow | +| `RDK_LOG_DEBUG` | 5 | Debug-level messages | Detailed debugging information | +| `RDK_LOG_TRACE` | 6 | Trace-level messages | Very detailed execution tracing | +| `RDK_LOG_NONE` | 7 | No logging | Disable all logging | + +### Log Level Hierarchy + +Setting a log level enables that level and all higher priority levels: + +``` +TRACE → DEBUG → INFO → NOTICE → WARN → ERROR → FATAL +``` + +**Example**: Setting `DEBUG` enables DEBUG, INFO, NOTICE, WARN, ERROR, and FATAL messages. + +### Legacy Compatibility + +For backward compatibility with legacy RDK components: + +```c +#define RDK_LOG_TRACE1 RDK_LOG_TRACE +#define RDK_LOG_TRACE2 RDK_LOG_TRACE +// ... up to RDK_LOG_TRACE9 +``` + +## Utilities + +### rdklogctrl - Runtime Log Control + +**Location**: `utils/rdklogctrl` + +**Purpose**: Command-line utility for modifying log levels of running processes. + +**Usage**: +```bash +rdklogctrl +``` + +**Examples**: +```bash +# Enable debug logging for network module +rdklogctrl receiver LOG.RDK.NETWORK DEBUG + +# Disable all logging for test module +rdklogctrl myapp LOG.RDK.TEST NONE + +# Turn off only error logs (keep others) +rdklogctrl player LOG.RDK.AUDIO ~ERROR +``` + +### rdklogmilestone - Milestone Utility + +**Location**: `utils/rdklogmilestone.c` + +**Purpose**: C utility for milestone logging from applications. + +**Usage**: +```bash +rdklogmilestone "APPLICATION_READY" +``` + +## Examples + +### Basic Application Integration + +```c +#include +#include +#include "rdk_logger.h" + +#define MODULE_NAME "LOG.RDK.MYAPP" + +int main() { + // Initialize logger + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Failed to initialize RDK Logger\n"); + return EXIT_FAILURE; + } + + // Log application startup + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application starting up\n"); + + // Example operations with different log levels + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Initializing components\n"); + + // Conditional debug logging for performance + if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_DEBUG)) { + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug mode enabled\n"); + } + + // Simulated error condition + int error_code = 42; + if (error_code != 0) { + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, + "Operation failed with error code %d\n", error_code); + } + + // Log application shutdown + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application shutting down\n"); + + rdk_logger_deinit(); + return EXIT_SUCCESS; +} +``` + +### Network Service Example + +```c +#include "rdk_logger.h" +#include +#include + +#define NET_MODULE "LOG.RDK.NETWORK" + +int start_server(int port) { + int server_fd; + struct sockaddr_in address; + + RDK_LOG(RDK_LOG_INFO, NET_MODULE, "Starting server on port %d\n", port); + + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + RDK_LOG(RDK_LOG_ERROR, NET_MODULE, + "Failed to create socket: %s\n", strerror(errno)); + return -1; + } + + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(port); + + if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { + RDK_LOG(RDK_LOG_ERROR, NET_MODULE, + "Failed to bind to port %d: %s\n", port, strerror(errno)); + close(server_fd); + return -1; + } + + if (listen(server_fd, 10) < 0) { + RDK_LOG(RDK_LOG_ERROR, NET_MODULE, + "Failed to listen on socket: %s\n", strerror(errno)); + close(server_fd); + return -1; + } + + RDK_LOG(RDK_LOG_NOTICE, NET_MODULE, + "Server successfully started and listening on port %d\n", port); + + return server_fd; +} + +void handle_client(int client_fd, struct sockaddr_in *client_addr) { + char client_ip[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &client_addr->sin_addr, client_ip, INET_ADDRSTRLEN); + + RDK_LOG(RDK_LOG_INFO, NET_MODULE, + "New client connected from %s:%d\n", + client_ip, ntohs(client_addr->sin_port)); + + // Handle client communication... + + RDK_LOG(RDK_LOG_DEBUG, NET_MODULE, + "Processing request from %s\n", client_ip); + + // When done + RDK_LOG(RDK_LOG_INFO, NET_MODULE, + "Client %s disconnected\n", client_ip); + close(client_fd); +} +``` + +### Configuration File Example + +Create `/etc/debug.ini`: +```ini +########################################################################## +# Production Configuration +########################################################################## + +# Default level - only warnings and errors +LOG.RDK.DEFAULT=WARN + +# Network debugging enabled +LOG.RDK.NETWORK=DEBUG + +# Application flow information +LOG.RDK.MYAPP=INFO + +# Security - errors only +LOG.RDK.SECURITY=ERROR + +# Disable test modules in production +LOG.RDK.TEST=NONE +LOG.RDK.UNITTEST=NONE + +# Media components +LOG.RDK.AUDIO=NOTICE +LOG.RDK.VIDEO=NOTICE +``` + +### Wrapper Function Example + +```c +#include "rdk_logger.h" +#include + +// Custom logging wrapper with timestamp +void my_log(rdk_LogLevel level, const char *module, const char *function, + int line, const char *format, ...) { + if (!rdk_dbg_enabled(module, level)) { + return; // Early return if logging disabled + } + + va_list args; + va_start(args, format); + + // Create enhanced format with function and line info + char enhanced_format[512]; + snprintf(enhanced_format, sizeof(enhanced_format), + "[%s:%d] %s", function, line, format); + + rdk_logger_msg_vsprintf(level, module, enhanced_format, args); + va_end(args); +} + +// Convenience macro +#define MY_LOG(level, module, format, ...) \ + my_log(level, module, __FUNCTION__, __LINE__, format, ##__VA_ARGS__) + +// Usage +int main() { + RDK_LOGGER_INIT(); + + MY_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Application started\n"); + MY_LOG(RDK_LOG_DEBUG, "LOG.RDK.MYAPP", "Variable value: %d\n", 42); + + rdk_logger_deinit(); + return 0; +} +``` + +## Error Handling + +### Return Codes + +All initialization functions return `rdk_Error` type: + +```c +typedef uint32_t rdk_Error; +#define RDK_SUCCESS 0 +``` + +**Common Error Scenarios**: +- Configuration file not found +- Invalid configuration format +- Memory allocation failures +- Log4C initialization errors + +### Error Handling Pattern + +```c +rdk_Error init_logging(const char *config_file) { + rdk_Error ret = rdk_logger_init(config_file); + if (ret != RDK_SUCCESS) { + fprintf(stderr, "Logger initialization failed: %u\n", ret); + fprintf(stderr, "Falling back to stdout logging\n"); + // Implement fallback logging mechanism + return ret; + } + return RDK_SUCCESS; +} +``` + +### Graceful Degradation + +```c +int main() { + // Try to initialize logger + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Warning: RDK Logger initialization failed\n"); + fprintf(stderr, "Continuing with fprintf logging\n"); + + // Application can continue with basic printf/fprintf + printf("Application started (no RDK logging)\n"); + } else { + RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.MYAPP", "Application started\n"); + } + + // Rest of application... + + return 0; +} +``` + +## Best Practices + +### 1. Module Naming +```c +// Good - descriptive and consistent +#define AUDIO_MODULE "LOG.RDK.AUDIO" +#define NETWORK_MODULE "LOG.RDK.NETWORK" +#define DATABASE_MODULE "LOG.RDK.DATABASE" + +// Avoid - generic or unclear names +#define MODULE "LOG.RDK.APP" +#define MY_MODULE "LOG.RDK.THING" +``` + +### 2. Performance Optimization +```c +// Check if logging is enabled before expensive operations +if (rdk_dbg_enabled("LOG.RDK.MYAPP", RDK_LOG_DEBUG)) { + char *expensive_debug_info = generate_debug_dump(); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.MYAPP", "Debug: %s\n", expensive_debug_info); + free(expensive_debug_info); +} + +// Use appropriate log levels +RDK_LOG(RDK_LOG_FATAL, module, "System crash: %s\n", reason); // System unusable +RDK_LOG(RDK_LOG_ERROR, module, "Failed to connect: %s\n", err); // Error conditions +RDK_LOG(RDK_LOG_WARN, module, "Retrying connection\n"); // Warnings +RDK_LOG(RDK_LOG_NOTICE, module, "Service started\n"); // Important events +RDK_LOG(RDK_LOG_INFO, module, "Processing request\n"); // General info +RDK_LOG(RDK_LOG_DEBUG, module, "Variable x = %d\n", x); // Debug details +RDK_LOG(RDK_LOG_TRACE, module, "Entering function\n"); // Function tracing +``` + +### 3. Thread Safety +```c +// RDK Logger is thread-safe, but avoid race conditions in your logic +void worker_thread(void *arg) { + int thread_id = *(int*)arg; + + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.WORKER", + "Worker thread %d started\n", thread_id); + + // Worker logic... + + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.WORKER", + "Worker thread %d finished\n", thread_id); +} +``` + +### 4. Configuration Management +```c +// Check for override config file +const char* get_config_file() { + if (access("/nvram/debug.ini", F_OK) == 0) { + return "/nvram/debug.ini"; // Development/debug config + } + return "/etc/debug.ini"; // Production config +} + +// Initialize with appropriate config +rdk_Error ret = rdk_logger_init(get_config_file()); +``` + +### 5. Structured Logging +```c +// Include relevant context in log messages +RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.NETWORK", + "Connection failed: host=%s, port=%d, error=%s\n", + hostname, port, strerror(errno)); + +// Use consistent formats for similar events +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.SERVICE", + "SERVICE_START: name=%s, pid=%d, version=%s\n", + service_name, getpid(), version); +``` + +### 6. Cleanup +```c +// Always clean up in signal handlers and exit paths +void signal_handler(int sig) { + RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.MYAPP", + "Received signal %d, shutting down\n", sig); + rdk_logger_deinit(); + exit(0); +} + +int main() { + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + + RDK_LOGGER_INIT(); + + // Application logic... + + rdk_logger_deinit(); + return 0; +} +``` + +--- + +**Note**: This documentation covers RDK Logger API version as implemented in the current codebase. For the most up-to-date information, refer to the source code and header files. + diff --git a/docs/MIGRATION_GUIDE.md b/docs/MIGRATION_GUIDE.md new file mode 100644 index 0000000..9f72735 --- /dev/null +++ b/docs/MIGRATION_GUIDE.md @@ -0,0 +1,363 @@ +# RDK Logger Migration Guide + +## Overview + +This guide helps developers migrate from other logging systems to RDK Logger and upgrade existing RDK Logger implementations. + +## Migration from printf/fprintf + +### Before (Legacy Code) +```c +#include + +int main() { + printf("Application started\n"); + fprintf(stderr, "Error: Connection failed\n"); + printf("Debug: value = %d\n", value); + return 0; +} +``` + +### After (RDK Logger) +```c +#include "rdk_logger.h" + +#define MODULE_NAME "LOG.RDK.MYAPP" + +int main() { + // Initialize logger + RDK_LOGGER_INIT(); + + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application started\n"); + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, "Error: Connection failed\n"); + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug: value = %d\n", value); + + rdk_logger_deinit(); + return 0; +} +``` + +## Migration from syslog + +### Before (syslog) +```c +#include + +int main() { + openlog("myapp", LOG_PID, LOG_USER); + + syslog(LOG_INFO, "Application started"); + syslog(LOG_ERR, "Connection failed: %s", strerror(errno)); + syslog(LOG_DEBUG, "Processing item %d", item_id); + + closelog(); + return 0; +} +``` + +### After (RDK Logger) +```c +#include "rdk_logger.h" + +#define MODULE_NAME "LOG.RDK.MYAPP" + +int main() { + RDK_LOGGER_INIT(); + + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Application started\n"); + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, "Connection failed: %s\n", strerror(errno)); + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Processing item %d\n", item_id); + + rdk_logger_deinit(); + return 0; +} +``` + +### Log Level Mapping + +| syslog Level | RDK Logger Level | Description | +|--------------|------------------|-------------| +| LOG_EMERG | RDK_LOG_FATAL | System unusable | +| LOG_ALERT | RDK_LOG_FATAL | Action must be taken immediately | +| LOG_CRIT | RDK_LOG_FATAL | Critical conditions | +| LOG_ERR | RDK_LOG_ERROR | Error conditions | +| LOG_WARNING | RDK_LOG_WARN | Warning conditions | +| LOG_NOTICE | RDK_LOG_NOTICE | Normal but significant condition | +| LOG_INFO | RDK_LOG_INFO | Informational messages | +| LOG_DEBUG | RDK_LOG_DEBUG | Debug-level messages | + +## Migration from Custom Logging + +### Wrapper Approach +If you have existing custom logging macros, you can create wrapper functions: + +```c +// Legacy logging system +#define OLD_LOG_ERROR(fmt, ...) old_log_function(ERROR_LEVEL, fmt, ##__VA_ARGS__) +#define OLD_LOG_INFO(fmt, ...) old_log_function(INFO_LEVEL, fmt, ##__VA_ARGS__) + +// Migration wrapper +#define LOG_ERROR(fmt, ...) RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, fmt, ##__VA_ARGS__) +#define LOG_INFO(fmt, ...) RDK_LOG(RDK_LOG_INFO, MODULE_NAME, fmt, ##__VA_ARGS__) + +// Now replace OLD_LOG_* with LOG_* throughout your codebase +``` + +### Gradual Migration +You can run both systems in parallel during migration: + +```c +#include "rdk_logger.h" +#include "old_logger.h" + +#define DUAL_LOG(level, old_level, fmt, ...) do { \ + RDK_LOG(level, MODULE_NAME, fmt, ##__VA_ARGS__); \ + old_log_function(old_level, fmt, ##__VA_ARGS__); \ +} while(0) + +// Use DUAL_LOG during migration, then switch to RDK_LOG +``` + +## Configuration Migration + +### Converting Log Levels +Create a migration script to convert existing configuration: + +```bash +#!/bin/bash +# migrate_config.sh + +# Convert old format to debug.ini format +old_config="/etc/old_logger.conf" +new_config="/etc/debug.ini" + +echo "# Migrated configuration" > $new_config +echo "LOG.RDK.DEFAULT=WARNING" >> $new_config + +# Parse old configuration and convert +while IFS='=' read -r module level; do + case $level in + "error") new_level="ERROR" ;; + "warning") new_level="WARN" ;; + "info") new_level="INFO" ;; + "debug") new_level="DEBUG" ;; + *) new_level="NOTICE" ;; + esac + echo "LOG.RDK.$module=$new_level" >> $new_config +done < $old_config +``` + +## Advanced Migration Patterns + +### Conditional Compilation +Support both old and new logging during transition: + +```c +#ifdef USE_RDK_LOGGER + #include "rdk_logger.h" + #define APP_LOG(level, fmt, ...) RDK_LOG(level, MODULE_NAME, fmt, ##__VA_ARGS__) + #define APP_LOG_INIT() RDK_LOGGER_INIT() + #define APP_LOG_CLEANUP() rdk_logger_deinit() +#else + #include "old_logger.h" + #define APP_LOG(level, fmt, ...) old_log(level, fmt, ##__VA_ARGS__) + #define APP_LOG_INIT() old_log_init() + #define APP_LOG_CLEANUP() old_log_cleanup() +#endif + +int main() { + APP_LOG_INIT(); + APP_LOG(RDK_LOG_INFO, "Application started\n"); + // ... application code ... + APP_LOG_CLEANUP(); + return 0; +} +``` + +### Performance Comparison +Test performance impact during migration: + +```c +#include + +void performance_test() { + clock_t start, end; + int iterations = 10000; + + // Test RDK Logger performance + start = clock(); + for (int i = 0; i < iterations; i++) { + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Test message %d\n", i); + } + end = clock(); + + double rdk_time = ((double)(end - start)) / CLOCKS_PER_SEC; + printf("RDK Logger: %f seconds for %d messages\n", rdk_time, iterations); +} +``` + +## Common Migration Issues + +### Issue 1: Missing Newlines +**Problem**: RDK Logger expects newlines in format strings. +```c +// Wrong +RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Message"); + +// Correct +RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Message\n"); +``` + +### Issue 2: Module Name Format +**Problem**: Incorrect module naming convention. +```c +// Wrong +RDK_LOG(RDK_LOG_INFO, "MYAPP", "Message\n"); + +// Correct +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Message\n"); +``` + +### Issue 3: Initialization Order +**Problem**: Logging before initialization. +```c +// Wrong +int main() { + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Starting\n"); // Will fail + RDK_LOGGER_INIT(); +} + +// Correct +int main() { + RDK_LOGGER_INIT(); + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Starting\n"); +} +``` + +### Issue 4: Thread Safety +**Problem**: Initialization in multi-threaded environment. +```c +// Wrong - race condition +void thread_function() { + RDK_LOGGER_INIT(); // Multiple threads calling init + // ... +} + +// Correct - initialize once in main thread +int main() { + RDK_LOGGER_INIT(); + + // Create threads after initialization + pthread_create(&thread, NULL, thread_function, NULL); +} +``` + +## Testing Migration + +### Validation Script +```bash +#!/bin/bash +# validate_migration.sh + +echo "Testing RDK Logger migration..." + +# Test 1: Configuration file exists +if [ ! -f /etc/debug.ini ]; then + echo "ERROR: debug.ini not found" + exit 1 +fi + +# Test 2: Module names follow convention +if ! grep -q "LOG.RDK." /etc/debug.ini; then + echo "WARNING: No LOG.RDK modules found in config" +fi + +# Test 3: Test application logging +./test_app > /tmp/test_output.log 2>&1 + +if grep -q "LOG.RDK" /tmp/test_output.log; then + echo "SUCCESS: RDK Logger output detected" +else + echo "ERROR: No RDK Logger output found" + exit 1 +fi + +echo "Migration validation complete" +``` + +### Unit Test Example +```c +#include +#include "rdk_logger.h" + +void test_migration() { + // Test initialization + assert(RDK_LOGGER_INIT() == RDK_SUCCESS); + + // Test logging levels + assert(rdk_dbg_enabled("LOG.RDK.TEST", RDK_LOG_ERROR) == TRUE); + + // Test cleanup + assert(rdk_logger_deinit() == RDK_SUCCESS); + + printf("Migration tests passed\n"); +} +``` + +## Migration Checklist + +- [ ] Review existing logging calls and categorize by log level +- [ ] Create module name mapping (old names → LOG.RDK.* names) +- [ ] Update configuration files to debug.ini format +- [ ] Replace logging function calls with RDK_LOG macros +- [ ] Add RDK_LOGGER_INIT() and rdk_logger_deinit() calls +- [ ] Update build system to link RDK Logger libraries +- [ ] Test logging output and configuration +- [ ] Validate runtime log level changes work +- [ ] Update documentation and deployment scripts +- [ ] Train team on new logging system usage + +## Post-Migration Optimization + +### 1. Performance Tuning +```c +// Use conditional logging for expensive debug operations +if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_DEBUG)) { + char *debug_dump = expensive_debug_function(); + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug: %s\n", debug_dump); + free(debug_dump); +} +``` + +### 2. Configuration Optimization +```ini +# Production config - minimal logging +LOG.RDK.DEFAULT=ERROR + +# Development config - detailed logging +LOG.RDK.DEFAULT=DEBUG +LOG.RDK.NETWORK=TRACE +LOG.RDK.DATABASE=DEBUG +``` + +### 3. Monitoring Integration +```c +// Add metrics for log message rates +void log_with_metrics(rdk_LogLevel level, const char *module, + const char *format, ...) { + static int log_count = 0; + log_count++; + + if (log_count % 1000 == 0) { + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.METRICS", + "Logged %d messages\n", log_count); + } + + va_list args; + va_start(args, format); + rdk_logger_msg_vsprintf(level, module, format, args); + va_end(args); +} +``` + +This migration guide provides a comprehensive approach to transitioning to RDK Logger while maintaining system stability and performance. \ No newline at end of file diff --git a/docs/QUICK_REFERENCE.md b/docs/QUICK_REFERENCE.md new file mode 100644 index 0000000..d2ab5d3 --- /dev/null +++ b/docs/QUICK_REFERENCE.md @@ -0,0 +1,336 @@ +# RDK Logger Quick Reference + +## Essential Functions + +### Initialization +```c +#include "rdk_logger.h" + +// Standard initialization (uses /etc/debug.ini or /nvram/debug.ini) +RDK_LOGGER_INIT(); + +// Custom config file +rdk_logger_init("/path/to/custom/debug.ini"); + +// Extended initialization with file logging +rdk_logger_ext_config_t config = { + .fileName = "app.log", + .logdir = "/var/log/", + .maxSize = 1024*1024, // 1MB + .maxCount = 5 // Keep 5 files +}; +rdk_logger_ext_init(&config); + +// Cleanup +rdk_logger_deinit(); +``` + +### Logging +```c +// Basic logging +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Message\n"); + +// Formatted logging +RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.MYAPP", "Error %d: %s\n", errno, strerror(errno)); + +// Performance-conscious logging +if (rdk_dbg_enabled("LOG.RDK.MYAPP", RDK_LOG_DEBUG)) { + char *expensive_data = generate_debug_info(); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.MYAPP", "Debug: %s\n", expensive_data); + free(expensive_data); +} +``` + +## Log Levels (Priority Order) + +| Level | Macro | When to Use | +|-------|-------|-------------| +| FATAL | `RDK_LOG_FATAL` | System crash, unusable | +| ERROR | `RDK_LOG_ERROR` | Operation failures | +| WARN | `RDK_LOG_WARN` | Potential problems | +| NOTICE| `RDK_LOG_NOTICE` | Important events | +| INFO | `RDK_LOG_INFO` | General information | +| DEBUG | `RDK_LOG_DEBUG` | Debugging details | +| TRACE | `RDK_LOG_TRACE` | Function tracing | + +## Configuration (debug.ini) + +```ini +# Default level for all modules +LOG.RDK.DEFAULT=WARNING + +# Module-specific levels +LOG.RDK.NETWORK=DEBUG +LOG.RDK.AUDIO=INFO +LOG.RDK.VIDEO=NOTICE +LOG.RDK.TEST=NONE +``` + +### Config File Locations (Priority Order) +1. `/nvram/debug.ini` (override - highest priority) +2. `/etc/debug.ini` (default) +3. Custom path via `rdk_logger_init(path)` + +## Runtime Control + +### rdklogctrl Command +```bash +# Set log level for module +rdklogctrl + +# Examples +rdklogctrl myapp LOG.RDK.NETWORK DEBUG +rdklogctrl receiver LOG.RDK.AUDIO INFO +rdklogctrl player LOG.RDK.VIDEO ERROR + +# Disable specific level (~ prefix) +rdklogctrl myapp LOG.RDK.NETWORK ~DEBUG + +# Available levels +FATAL ERROR WARN NOTICE INFO DEBUG TRACE NONE +``` + +### Programmatic Control +```c +// Check if level is enabled +if (rdk_dbg_enabled("LOG.RDK.MYAPP", RDK_LOG_DEBUG)) { + // Debug logging is enabled +} + +// Enable/disable level at runtime +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, TRUE); // Enable +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, FALSE); // Disable + +// Convert string to log level +rdk_LogLevel level = rdk_logger_level_from_string("INFO"); +``` + +## Module Naming Convention + +### Correct Format +```c +#define MODULE_NAME "LOG.RDK.MYAPP" +#define NETWORK_MODULE "LOG.RDK.NETWORK" +#define AUDIO_MODULE "LOG.RDK.AUDIO" +``` + +### Common Mistakes +```c +// ❌ Wrong - missing LOG.RDK prefix +RDK_LOG(RDK_LOG_INFO, "MYAPP", "Message\n"); + +// ❌ Wrong - case sensitivity +RDK_LOG(RDK_LOG_INFO, "log.rdk.myapp", "Message\n"); + +// ❌ Wrong - extra spaces +RDK_LOG(RDK_LOG_INFO, "LOG.RDK. MYAPP", "Message\n"); + +// ✅ Correct +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Message\n"); +``` + +## Common Patterns + +### Application Template +```c +#include "rdk_logger.h" +#include + +#define MODULE_NAME "LOG.RDK.MYAPP" + +void cleanup_handler(int sig) { + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Shutting down (signal %d)\n", sig); + rdk_logger_deinit(); + exit(0); +} + +int main() { + // Setup signal handlers + signal(SIGTERM, cleanup_handler); + signal(SIGINT, cleanup_handler); + + // Initialize logger + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Logger init failed\n"); + return 1; + } + + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application started\n"); + + // Main application logic + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Processing...\n"); + + // Cleanup + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application finished\n"); + rdk_logger_deinit(); + return 0; +} +``` + +### Error Handling Pattern +```c +int connect_to_server(const char *hostname, int port) { + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Connecting to %s:%d\n", hostname, port); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, + "Socket creation failed: %s\n", strerror(errno)); + return -1; + } + + // Connection logic... + + if (connect_result < 0) { + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, + "Connection to %s:%d failed: %s\n", + hostname, port, strerror(errno)); + close(sock); + return -1; + } + + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, + "Successfully connected to %s:%d\n", hostname, port); + return sock; +} +``` + +### Performance-Conscious Logging +```c +void process_data(const data_t *data) { + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Processing data batch\n"); + + // Only generate expensive debug info if debug logging is enabled + if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_DEBUG)) { + char debug_info[1024]; + generate_debug_summary(data, debug_info, sizeof(debug_info)); + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Data details: %s\n", debug_info); + } + + // Trace function entry/exit only if trace is enabled + if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_TRACE)) { + RDK_LOG(RDK_LOG_TRACE, MODULE_NAME, "Entering %s\n", __FUNCTION__); + } + + // Process data... + + if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_TRACE)) { + RDK_LOG(RDK_LOG_TRACE, MODULE_NAME, "Exiting %s\n", __FUNCTION__); + } +} +``` + +## Build Integration + +### Makefile +```makefile +# Compiler flags +CFLAGS += -I/usr/include/rdklogger + +# Linker flags +LDFLAGS += -lrdkloggers -llog4c -lglib-2.0 + +# Example target +myapp: myapp.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) +``` + +### CMake +```cmake +# Find required libraries +find_package(PkgConfig REQUIRED) +pkg_check_modules(GLIB REQUIRED glib-2.0) + +# Link libraries +target_link_libraries(myapp + rdkloggers + log4c + ${GLIB_LIBRARIES} +) + +# Include directories +target_include_directories(myapp PRIVATE + /usr/include/rdklogger + ${GLIB_INCLUDE_DIRS} +) +``` + +## Debugging Tips + +### Check Configuration +```bash +# Verify config file exists and is readable +cat /etc/debug.ini + +# Test with specific module +grep "LOG.RDK.MYAPP" /etc/debug.ini + +# Check default level +grep "LOG.RDK.DEFAULT" /etc/debug.ini +``` + +### Test Logging +```c +// Test program to verify logging works +#include "rdk_logger.h" + +int main() { + printf("Testing RDK Logger...\n"); + + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + printf("❌ Init failed\n"); + return 1; + } + printf("✅ Init succeeded\n"); + + const char *module = "LOG.RDK.TEST"; + + printf("Testing log levels:\n"); + RDK_LOG(RDK_LOG_FATAL, module, "❌ FATAL message\n"); + RDK_LOG(RDK_LOG_ERROR, module, "🔴 ERROR message\n"); + RDK_LOG(RDK_LOG_WARN, module, "🟡 WARN message\n"); + RDK_LOG(RDK_LOG_NOTICE, module, "🔵 NOTICE message\n"); + RDK_LOG(RDK_LOG_INFO, module, "ℹ️ INFO message\n"); + RDK_LOG(RDK_LOG_DEBUG, module, "🐛 DEBUG message\n"); + RDK_LOG(RDK_LOG_TRACE, module, "🔍 TRACE message\n"); + + rdk_logger_deinit(); + printf("✅ Test completed\n"); + return 0; +} +``` + +### Runtime Control Test +```bash +# Start your application in background +./myapp & +APP_PID=$! + +# Change log level +rdklogctrl myapp LOG.RDK.TEST DEBUG + +# Check if change took effect (application should show more logs) + +# Cleanup +kill $APP_PID +``` + +## Error Codes + +| Code | Meaning | Action | +|------|---------|---------| +| 0 | `RDK_SUCCESS` | Operation successful | +| Non-zero | Various errors | Check config file, permissions, dependencies | + +## Dependencies + +### Required Libraries +- `librdkloggers` - RDK Logger library +- `liblog4c` - Log4C logging framework +- `libglib-2.0` - GLib utility library + +### Optional Tools +- `rdklogctrl` - Runtime log control utility +- `rdklogmilestone` - Milestone logging utility + +This quick reference provides the most commonly needed information for day-to-day RDK Logger usage. \ No newline at end of file diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md new file mode 100644 index 0000000..259fb52 --- /dev/null +++ b/docs/TROUBLESHOOTING.md @@ -0,0 +1,514 @@ +# RDK Logger Troubleshooting Guide + +## Common Issues and Solutions + +### 1. Logger Initialization Failures + +#### Issue: `rdk_logger_init()` returns error +**Symptoms:** +``` +Logger initialization failed with return: -1 +config_file ini is not found +``` + +**Causes and Solutions:** + +**Cause 1: Configuration file not found** +```bash +# Check if config file exists +ls -la /etc/debug.ini +ls -la /nvram/debug.ini +``` + +**Solution:** +```bash +# Create default configuration +sudo cp debug.ini.sample /etc/debug.ini +sudo chmod 644 /etc/debug.ini +``` + +**Cause 2: Permission issues** +```bash +# Check file permissions +ls -la /etc/debug.ini +``` + +**Solution:** +```bash +# Fix permissions +sudo chown root:root /etc/debug.ini +sudo chmod 644 /etc/debug.ini +``` + +**Cause 3: Invalid configuration format** +```ini +# Wrong format +INVALID.FORMAT=DEBUG + +# Correct format +LOG.RDK.MYAPP=DEBUG +``` + +#### Issue: Multiple initialization calls +**Problem:** +```c +// This can cause issues +RDK_LOGGER_INIT(); +RDK_LOGGER_INIT(); // Second call may fail +``` + +**Solution:** +```c +static int logger_initialized = 0; + +int init_logger_once() { + if (!logger_initialized) { + if (RDK_LOGGER_INIT() == RDK_SUCCESS) { + logger_initialized = 1; + return 0; + } + return -1; + } + return 0; // Already initialized +} +``` + +### 2. No Log Output + +#### Issue: Messages not appearing despite configuration + +**Debugging Steps:** + +**Step 1: Verify initialization** +```c +#include "rdk_logger.h" + +int main() { + printf("Before RDK_LOGGER_INIT\n"); + rdk_Error ret = RDK_LOGGER_INIT(); + printf("RDK_LOGGER_INIT returned: %d\n", ret); + + printf("Testing log output...\n"); + RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.TEST", "Test error message\n"); + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.TEST", "Test info message\n"); + + rdk_logger_deinit(); + return 0; +} +``` + +**Step 2: Check configuration** +```bash +# Verify config file content +cat /etc/debug.ini + +# Check for your module +grep "LOG.RDK.TEST" /etc/debug.ini + +# Check default level +grep "LOG.RDK.DEFAULT" /etc/debug.ini +``` + +**Step 3: Test log level checking** +```c +// Debug log level checking +const char *module = "LOG.RDK.TEST"; +printf("ERROR enabled: %d\n", rdk_dbg_enabled(module, RDK_LOG_ERROR)); +printf("WARN enabled: %d\n", rdk_dbg_enabled(module, RDK_LOG_WARN)); +printf("INFO enabled: %d\n", rdk_dbg_enabled(module, RDK_LOG_INFO)); +printf("DEBUG enabled: %d\n", rdk_dbg_enabled(module, RDK_LOG_DEBUG)); +``` + +**Step 4: Check environment** +```bash +# Verify log4c is available +ldd your_application | grep log4c + +# Check if log4c config exists +find /etc -name "*log4c*" 2>/dev/null +``` + +### 3. Runtime Log Control Issues + +#### Issue: `rdklogctrl` not working + +**Problem:** Changes don't take effect +```bash +# Command appears to work but no change +rdklogctrl myapp LOG.RDK.NETWORK DEBUG +``` + +**Debugging:** + +**Step 1: Verify process name** +```bash +# Check exact process name +ps aux | grep myapp + +# Use exact name from ps output +rdklogctrl "myapp_process_name" LOG.RDK.NETWORK DEBUG +``` + +**Step 2: Check process accessibility** +```bash +# Verify process is running as expected user +ps -ef | grep myapp + +# Check if process accepts socket connections +netstat -tlnp | grep :12035 +``` + +**Step 3: Test with simple module** +```bash +# Try with a known module first +rdklogctrl myapp LOG.RDK.DEFAULT INFO +``` + +#### Issue: Dynamic logging not persistent +**Problem:** Log level changes revert after application restart + +**Explanation:** `rdklogctrl` changes are runtime-only. For persistent changes, modify `debug.ini`: + +```bash +# For persistent changes +sudo nano /etc/debug.ini + +# Add or modify +LOG.RDK.NETWORK=DEBUG +``` + +### 4. Performance Issues + +#### Issue: Logging causing performance degradation + +**Problem:** Application becomes slow when debug logging is enabled + +**Solution 1: Conditional logging** +```c +// Wrong - always evaluates expensive_function() +RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug: %s\n", expensive_function()); + +// Right - only calls expensive_function() if debug is enabled +if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_DEBUG)) { + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug: %s\n", expensive_function()); +} +``` + +**Solution 2: Optimize log levels** +```ini +# Production config - minimal logging +LOG.RDK.DEFAULT=ERROR +LOG.RDK.CRITICAL_MODULE=WARN + +# Only enable debug for specific investigation +LOG.RDK.PROBLEM_MODULE=DEBUG +``` + +**Solution 3: Measure logging overhead** +```c +#include + +void measure_logging_performance() { + clock_t start = clock(); + + for (int i = 0; i < 10000; i++) { + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.PERF", "Test message %d\n", i); + } + + clock_t end = clock(); + double time_spent = ((double)(end - start)) / CLOCKS_PER_SEC; + + printf("10000 log messages took %f seconds\n", time_spent); +} +``` + +### 5. Memory Issues + +#### Issue: Memory leaks or crashes + +**Problem:** Application crashes or shows memory leaks related to logging + +**Solution 1: Proper cleanup** +```c +#include + +void cleanup_handler(int sig) { + RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.MAIN", "Received signal %d, cleaning up\n", sig); + rdk_logger_deinit(); + exit(0); +} + +int main() { + // Register signal handlers + signal(SIGTERM, cleanup_handler); + signal(SIGINT, cleanup_handler); + + RDK_LOGGER_INIT(); + + // Application logic... + + rdk_logger_deinit(); + return 0; +} +``` + +**Solution 2: Check for double-free issues** +```c +// Avoid static string modification +char buffer[256]; +snprintf(buffer, sizeof(buffer), "Dynamic message: %d", value); +RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "%s\n", buffer); +``` + +**Solution 3: Valgrind debugging** +```bash +# Run with valgrind to detect memory issues +valgrind --leak-check=full --show-leak-kinds=all ./your_app + +# Look for leaks in librdkloggers or liblog4c +``` + +### 6. Multi-threading Issues + +#### Issue: Garbled log output or crashes in multi-threaded applications + +**Problem:** Multiple threads logging simultaneously causing corruption + +**Solution 1: RDK Logger is thread-safe (internal synchronization)** +```c +#include + +void* worker_thread(void* arg) { + int thread_id = *(int*)arg; + + // This is safe - RDK Logger handles synchronization + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.WORKER", + "Thread %d: Starting work\n", thread_id); + + // Do work... + + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.WORKER", + "Thread %d: Work completed\n", thread_id); + + return NULL; +} +``` + +**Solution 2: If issues persist, add application-level synchronization** +```c +#include + +static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define SAFE_LOG(level, module, format, ...) do { \ + pthread_mutex_lock(&log_mutex); \ + RDK_LOG(level, module, format, ##__VA_ARGS__); \ + pthread_mutex_unlock(&log_mutex); \ +} while(0) +``` + +### 7. Configuration Issues + +#### Issue: Module-specific settings not working + +**Problem:** Settings in debug.ini not taking effect for specific modules + +**Debug steps:** + +**Step 1: Verify module name format** +```ini +# Wrong formats +MYAPP=DEBUG # Missing LOG.RDK prefix +LOG.RDK.MyApp=DEBUG # Case sensitive +LOG.RDK. MYAPP=DEBUG # Extra space + +# Correct format +LOG.RDK.MYAPP=DEBUG +``` + +**Step 2: Check for syntax errors** +```bash +# Validate config file syntax +grep -n "=" /etc/debug.ini | grep -v "^#" + +# Check for invalid characters +hexdump -C /etc/debug.ini | head -20 +``` + +**Step 3: Test with minimal config** +```ini +# Minimal test config +LOG.RDK.DEFAULT=INFO +LOG.RDK.TEST=DEBUG +``` + +#### Issue: Case sensitivity problems + +**Problem:** Module names not matching due to case differences + +```c +// These are different modules +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MyApp", "Message\n"); // MyApp +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Message\n"); // MYAPP +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.myapp", "Message\n"); // myapp +``` + +**Solution:** Use consistent naming convention +```c +// Define module name once +#define MODULE_NAME "LOG.RDK.MYAPP" + +// Use throughout application +RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Message\n"); +``` + +### 8. Build and Linking Issues + +#### Issue: Undefined references during compilation + +**Problem:** +``` +undefined reference to `rdk_logger_init' +undefined reference to `rdk_logger_msg_printf' +``` + +**Solution 1: Check linking order** +```bash +# Wrong order +gcc -lrdkloggers myapp.c -llog4c -lglib-2.0 + +# Correct order +gcc myapp.c -lrdkloggers -llog4c -lglib-2.0 +``` + +**Solution 2: Verify library installation** +```bash +# Check if libraries are installed +ldconfig -p | grep rdkloggers +ldconfig -p | grep log4c + +# Find library files +find /usr -name "librdkloggers*" 2>/dev/null +find /usr -name "liblog4c*" 2>/dev/null +``` + +**Solution 3: Use pkg-config if available** +```bash +# Check for pkg-config files +pkg-config --list-all | grep rdk + +# If available, use pkg-config +gcc myapp.c `pkg-config --cflags --libs rdklogger` +``` + +### 9. Log File Issues + +#### Issue: Log files not being created or rotated + +**Problem:** Using `rdk_logger_ext_init()` but files not appearing + +**Debug steps:** + +**Step 1: Check directory permissions** +```c +rdk_logger_ext_config_t config = { + .fileName = "myapp.log", + .logdir = "/var/log/", // Check if writable + .maxSize = 1024 * 1024, + .maxCount = 5 +}; + +// Test directory access +if (access("/var/log/", W_OK) != 0) { + perror("Cannot write to /var/log/"); +} +``` + +**Step 2: Use accessible directory** +```c +rdk_logger_ext_config_t config = { + .fileName = "myapp.log", + .logdir = "/tmp/", // Use /tmp for testing + .maxSize = 1024 * 1024, + .maxCount = 5 +}; +``` + +**Step 3: Check log4c configuration** +```bash +# Look for log4c config files +find /etc -name "*log4c*" 2>/dev/null + +# Check log4c configuration +export LOG4C_APPENDER_FILE_FILENAME="/tmp/test.log" +./your_app +``` + +### 10. Debugging Tools and Techniques + +#### Environment Variables +```bash +# Enable log4c debugging +export LOG4C_PRIORITY=debug +export LOG4C_APPENDER=stdout + +# Run your application +./your_app +``` + +#### Debugging Configuration Loading +```c +#include "rdk_logger.h" + +void debug_config_loading() { + printf("Checking config files:\n"); + + // Check primary config + if (access("/etc/debug.ini", F_OK) == 0) { + printf("✓ /etc/debug.ini exists\n"); + } else { + printf("✗ /etc/debug.ini not found\n"); + } + + // Check override config + if (access("/nvram/debug.ini", F_OK) == 0) { + printf("✓ /nvram/debug.ini exists (will be used)\n"); + } else { + printf("✗ /nvram/debug.ini not found\n"); + } + + // Test initialization + rdk_Error ret = RDK_LOGGER_INIT(); + printf("Logger init result: %d (%s)\n", ret, + ret == RDK_SUCCESS ? "SUCCESS" : "FAILED"); +} +``` + +#### Network Debugging for rdklogctrl +```bash +# Check if dynamic logger port is listening +netstat -tlnp | grep :12035 + +# Test socket connection +telnet localhost 12035 + +# Monitor network traffic +tcpdump -i lo port 12035 +``` + +### Quick Reference Checklist + +When troubleshooting RDK Logger issues: + +1. **✓ Check configuration file exists and is readable** +2. **✓ Verify module names follow LOG.RDK.* convention** +3. **✓ Confirm logger initialization succeeded** +4. **✓ Test with simple log levels (ERROR, INFO)** +5. **✓ Check process name for rdklogctrl commands** +6. **✓ Verify library linking is correct** +7. **✓ Test with minimal configuration** +8. **✓ Check file permissions for log directories** +9. **✓ Use debugging tools (valgrind, gdb, strace)** +10. **✓ Enable log4c debugging if needed** + +This troubleshooting guide should help resolve most common issues with RDK Logger implementation and usage. \ No newline at end of file diff --git a/include/rdk_logger.h b/include/rdk_logger.h index a17a496..12cb3ba 100644 --- a/include/rdk_logger.h +++ b/include/rdk_logger.h @@ -76,13 +76,6 @@ * * @image html rdk_logger_architecture.jpg * - * @par RDK Logging Configuration - * @n Default level of logging is WARNING. Logging settings can be overriden by debug.ini - * @code - * - LOG.RDK. = INFO - * - LOG.RDK. = DEBUG - * @endcode - * * @par Logging Levels supported by RDK Logger. * Code | Description * -----|------------ From d186a560cdcb8385bac329daf3c18c0cfcd39e34 Mon Sep 17 00:00:00 2001 From: Karunakaran A <48997923+karuna2git@users.noreply.github.com> Date: Tue, 23 Sep 2025 12:25:27 -0400 Subject: [PATCH 18/37] RDKB-61752 : Add Legacy Function for Backward Compatibility (#23) Reason for change: Add rdk_dbg_* APIs for Backward Compatibility Test Procedure: Verify WiFi Motion Risks: Low Signed-off-by: dshett549 DEEPTHICHANDRASHEKAR_SHETTY@comcast.com Co-authored-by: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> --- include/rdk_logger.h | 9 +++++++++ src/rdk_debug.c | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/include/rdk_logger.h b/include/rdk_logger.h index 304646d..a17a496 100644 --- a/include/rdk_logger.h +++ b/include/rdk_logger.h @@ -284,6 +284,15 @@ void rdk_logger_log_onboard(const char *module, const char *msg, ...) __attribut */ void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, ...) __attribute__ ((format (printf, 3, 4))); +/** + * @brief legacy method to Log a message using a va_list. + * @param level Log level. + * @param module Module name. + * @param format Printf-style format string. + * @param args va_list of arguments. + */ +void rdk_dbg_MsgRaw1(rdk_LogLevel level, const char *module, const char *format, va_list args); + /** * @brief Convert a log level string to rdk_LogLevel enum. * @param level Log level as string (e.g., "INFO", "DEBUG"). diff --git a/src/rdk_debug.c b/src/rdk_debug.c index e6f88bd..b4903f0 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -100,6 +100,11 @@ void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char rdk_dbg_priv_log_msg(level, module, format, args); } +void rdk_dbg_MsgRaw1(rdk_LogLevel level, const char *module, const char *format, va_list args) +{ + rdk_dbg_priv_log_msg(level, module, format, args); +} + /** * @brief Function to sets a specific log level of a module. * From 35e2f745683395d3686969a695bd966cccad1027 Mon Sep 17 00:00:00 2001 From: Karunakaran A <48997923+karuna2git@users.noreply.github.com> Date: Tue, 23 Sep 2025 14:15:41 -0400 Subject: [PATCH 19/37] Update Documentation for RDKLogger (#24) * Updated the documentation Signed-off-by: Karunakaran A --- README.md | 129 +++ doc/rdklogger-doxygen.cfg | 1799 ------------------------------------- docs/API_DOCUMENTATION.md | 765 ++++++++++++++++ docs/MIGRATION_GUIDE.md | 363 ++++++++ docs/QUICK_REFERENCE.md | 336 +++++++ docs/TROUBLESHOOTING.md | 514 +++++++++++ include/rdk_logger.h | 7 - 7 files changed, 2107 insertions(+), 1806 deletions(-) delete mode 100644 doc/rdklogger-doxygen.cfg create mode 100644 docs/API_DOCUMENTATION.md create mode 100644 docs/MIGRATION_GUIDE.md create mode 100644 docs/QUICK_REFERENCE.md create mode 100644 docs/TROUBLESHOOTING.md diff --git a/README.md b/README.md index 43ab6ec..704e3ee 100644 --- a/README.md +++ b/README.md @@ -34,3 +34,132 @@ LOG.RDK.BAR=NONE ## Runtime Control Use the `rdklogctrl` utility to change log levels for modules at run time. + +```bash +# Set log level for a module +rdklogctrl + +# Examples +rdklogctrl myapp LOG.RDK.NETWORK DEBUG +rdklogctrl receiver LOG.RDK.AUDIO INFO + +# Available levels: FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE, NONE +``` + +## Quick Start + +### 1. Include Headers +```c +#include "rdk_logger.h" +``` + +### 2. Initialize and Use +```c +int main() { + // Initialize logger + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Failed to initialize RDK Logger\n"); + return -1; + } + + // Log messages + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Application started\n"); + RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.MYAPP", "Error: %s\n", strerror(errno)); + + // Cleanup + rdk_logger_deinit(); + return 0; +} +``` + +### 3. Build and Link +```bash +gcc myapp.c -lrdkloggers -llog4c -lglib-2.0 +``` + +## 📚 Complete Documentation + +This repository includes comprehensive documentation for all aspects of RDK Logger: + +### 📖 [API Documentation](docs/API_DOCUMENTATION.md) +**Complete developer reference** +- Detailed API function documentation with parameters and return values +- Architecture overview and capabilities +- Configuration system and debug.ini format +- Runtime control mechanisms and utilities +- Performance optimization and best practices +- Complete real-world examples and usage patterns + +### ⚡ [Quick Reference](docs/QUICK_REFERENCE.md) +**Essential information for daily use** +- Core function syntax and common patterns +- Log level hierarchy and usage guidelines +- Configuration snippets and examples +- Runtime control commands (rdklogctrl) +- Build system integration examples +- Debugging tips and test programs + +### 🔄 [Migration Guide](docs/MIGRATION_GUIDE.md) +**Transitioning from other logging systems** +- Step-by-step migration from printf/fprintf, syslog, and custom logging +- Log level mapping between different systems +- Configuration conversion techniques +- Common migration pitfalls and solutions +- Validation scripts and testing approaches + +### 🛠️ [Troubleshooting Guide](docs/TROUBLESHOOTING.md) +**Solutions for common issues** +- Initialization failures and configuration problems +- Missing log output debugging +- Runtime control issues +- Performance and memory problems +- Multi-threading complications +- Build and linking solutions + +## 🚀 Getting Started Paths + +### For New Users +1. **Read** the [Quick Start](#quick-start) section above +2. **Study** [API Documentation](docs/API_DOCUMENTATION.md) for comprehensive understanding +3. **Reference** [Quick Reference](docs/QUICK_REFERENCE.md) for daily syntax needs + +### For Migrating from Other Systems +1. **Identify** your current logging system in [Migration Guide](docs/MIGRATION_GUIDE.md) +2. **Follow** the step-by-step migration process +3. **Validate** using provided migration scripts and tests + +### For Troubleshooting +1. **Check** [Troubleshooting Guide](docs/TROUBLESHOOTING.md) for your specific issue +2. **Use** debugging techniques and tools provided +3. **Reference** [Quick Reference](docs/QUICK_REFERENCE.md) for correct syntax + +## Log Levels + +| Level | When to Use | +|-------|-------------| +| **FATAL** | System crash, unusable | +| **ERROR** | Operation failures | +| **WARN** | Potential problems | +| **NOTICE** | Important events | +| **INFO** | General information | +| **DEBUG** | Debugging details | +| **TRACE** | Function tracing | + +## Build Dependencies + +- **liblog4c-dev** - Log4C development headers +- **libglib2.0-dev** - GLib development headers +- **autotools** - For building from source + +## Repository Structure + +``` +rdk_logger/ +├── include/ # Header files (rdk_logger.h, etc.) +├── src/ # Source files +├── utils/ # Utility programs (rdklogctrl) +├── test/ # Test programs +├── unittests/ # Unit tests +├── debug.ini.sample # Example configuration +└── docs/ # Comprehensive documentation +``` diff --git a/doc/rdklogger-doxygen.cfg b/doc/rdklogger-doxygen.cfg deleted file mode 100644 index 45f1d0e..0000000 --- a/doc/rdklogger-doxygen.cfg +++ /dev/null @@ -1,1799 +0,0 @@ -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## -# Doxyfile 1.7.6.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need -# to put quotes around the project name if it contains spaces. - -PROJECT_NAME = "My Project" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = ./doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the -# itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man -# pages) or section (for LaTeX and RTF). - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -SYMBOL_CACHE_SIZE = 0 - -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this -# feature you need bibtex and perl available in the search path. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = ./include/rdk_logger.h - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when -# changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# style sheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# -# Qt Help Project / Custom Filters. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# -# Qt Help Project / Filter Attributes. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set -# GENERATE_TREEVIEW to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you -# could consider to set DISABLE_INDEX to NO when enabling this option. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension -# names that should be enabled during MathJax rendering. - -MATHJAX_EXTENSIONS = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See -# http://en.wikipedia.org/wiki/BibTeX for more info. - -LATEX_BIB_STYLE = plain - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the -# directory containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to -# set the path where dot can find it. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible in IE 9+ (other browsers do not have this requirement). - -DOT_IMAGE_FORMAT = png - -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files -# visible. Older versions of IE do not have SVG support. - -INTERACTIVE_SVG = NO - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = YES - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/docs/API_DOCUMENTATION.md b/docs/API_DOCUMENTATION.md new file mode 100644 index 0000000..3b3368e --- /dev/null +++ b/docs/API_DOCUMENTATION.md @@ -0,0 +1,765 @@ +# RDK Logger API Documentation + +## Table of Contents +1. [Overview](#overview) +2. [Architecture](#architecture) +3. [Installation & Build](#installation--build) +4. [Quick Start](#quick-start) +5. [Core APIs](#core-apis) +6. [Configuration](#configuration) +7. [Runtime Control](#runtime-control) +8. [Log Levels](#log-levels) +9. [Utilities](#utilities) +10. [Examples](#examples) +11. [Error Handling](#error-handling) +12. [Best Practices](#best-practices) + +## Overview + +RDK Logger is a comprehensive logging framework designed for RDK (Reference Design Kit) components. It provides: + +- **Centralized Configuration**: Single `debug.ini` file for all components +- **Runtime Control**: Dynamic log level changes without restart +- **Multi-level Logging**: Support for FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE +- **Module-specific Control**: Independent log levels per component/module +- **Performance Optimized**: Minimal overhead when logging is disabled +- **Thread-safe**: Safe for multi-threaded applications + +## Architecture + +``` +┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐ +│ Application │───▶│ RDK Logger │───▶│ Log Output │ +│ │ │ │ │ (stdout/file) │ +└─────────────────┘ └──────────────────┘ └─────────────────┘ + │ + ▼ + ┌──────────────────┐ + │ debug.ini │ + │ Configuration │ + └──────────────────┘ +``` + +The RDK Logger sits between your application and the actual log output, providing filtering, formatting, and runtime control capabilities. + +## Installation & Build + +### Prerequisites +- `liblog4c` - Log4C logging library +- `libglib-2.0` - GLib library +- `autotools` - For building from source + +### Build Instructions +```bash +# Configure and build +./configure +make + +# Install +sudo make install +``` + +### Linking in Your Project +```bash +# Compile flags +gcc -o myapp myapp.c -lrdkloggers -llog4c -lglib-2.0 +``` + +## Quick Start + +### 1. Include Headers +```c +#include "rdk_logger.h" +``` + +### 2. Initialize Logger +```c +int main() { + // Initialize with default config file (/etc/debug.ini) + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Failed to initialize RDK Logger\n"); + return -1; + } + + // Your application code here + + // Clean up + rdk_logger_deinit(); + return 0; +} +``` + +### 3. Log Messages +```c +// Basic logging +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Application started successfully\n"); + +// Formatted logging +int port = 8080; +RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.MYAPP", "Server listening on port %d\n", port); + +// Error logging +RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.MYAPP", "Failed to connect to database: %s\n", strerror(errno)); +``` + +## Core APIs + +### Initialization Functions + +#### `rdk_logger_init()` +```c +rdk_Error rdk_logger_init(const char* debugConfigFile); +``` +**Purpose**: Initialize the RDK Logger with a specific configuration file. + +**Parameters**: +- `debugConfigFile`: Path to the debug.ini configuration file + +**Returns**: `RDK_SUCCESS` on success, error code otherwise + +**Example**: +```c +rdk_Error ret = rdk_logger_init("/etc/debug.ini"); +if (ret != RDK_SUCCESS) { + printf("Logger initialization failed\n"); +} +``` + +#### `rdk_logger_ext_init()` +```c +rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config); +``` +**Purpose**: Extended initialization with custom log file configuration. + +**Parameters**: +- `config`: Pointer to extended configuration structure + +**Configuration Structure**: +```c +typedef struct rdk_logger_ext_config_t { + char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; // Log file name + char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; // Log directory path + long maxSize; // Max file size in bytes + long maxCount; // Max number of log files +} rdk_logger_ext_config_t; +``` + +**Example**: +```c +rdk_logger_ext_config_t config = { + .fileName = "myapp.log", + .logdir = "/var/log/", + .maxSize = 1024 * 1024, // 1MB + .maxCount = 5 // Keep 5 log files +}; +rdk_logger_ext_init(&config); +``` + +#### `rdk_logger_deinit()` +```c +rdk_Error rdk_logger_deinit(void); +``` +**Purpose**: Clean up and deinitialize the logger. + +**Returns**: `RDK_SUCCESS` on success + +### Logging Functions + +#### `RDK_LOG` Macro +```c +#define RDK_LOG rdk_logger_msg_printf +``` +**Purpose**: Primary logging macro for formatted messages. + +**Syntax**: +```c +RDK_LOG(level, module, format, ...); +``` + +**Parameters**: +- `level`: Log level (see [Log Levels](#log-levels)) +- `module`: Module name string (should match debug.ini entries) +- `format`: Printf-style format string +- `...`: Variable arguments for format string + +#### `rdk_logger_msg_printf()` +```c +void rdk_logger_msg_printf(rdk_LogLevel level, const char *module, const char *format, ...); +``` +**Purpose**: Core logging function with printf-style formatting. + +**Example**: +```c +rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.NETWORK", + "Connection established to %s:%d\n", hostname, port); +``` + +#### `rdk_logger_msg_vsprintf()` +```c +void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char *format, va_list args); +``` +**Purpose**: Logging function that accepts a `va_list` for wrapper functions. + +**Example**: +```c +void my_log_wrapper(rdk_LogLevel level, const char *module, const char *format, ...) { + va_list args; + va_start(args, format); + rdk_logger_msg_vsprintf(level, module, format, args); + va_end(args); +} +``` + +### Query and Control Functions + +#### `rdk_logger_is_logLevel_enabled()` +```c +rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); +``` +**Purpose**: Check if a specific log level is enabled for a module. + +**Returns**: `TRUE` if enabled, `FALSE` otherwise + +**Example**: +```c +if (rdk_logger_is_logLevel_enabled("LOG.RDK.MYAPP", RDK_LOG_DEBUG)) { + // Expensive debug computation only if debug logging is enabled + char *debug_info = generate_debug_info(); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.MYAPP", "Debug info: %s\n", debug_info); + free(debug_info); +} +``` + +#### `rdk_logger_enable_logLevel()` +```c +rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); +``` +**Purpose**: Dynamically enable or disable a log level for a module at runtime. + +**Parameters**: +- `module`: Module name +- `logLevel`: Log level to modify +- `enableLogLvl`: `TRUE` to enable, `FALSE` to disable + +**Returns**: `TRUE` if successful + +**Example**: +```c +// Enable debug logging temporarily +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, TRUE); + +// ... debug operations ... + +// Disable debug logging +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, FALSE); +``` + +### Utility Functions + +#### `rdk_logger_level_from_string()` +```c +rdk_LogLevel rdk_logger_level_from_string(const char* level); +``` +**Purpose**: Convert string representation to log level enum. + +**Parameters**: +- `level`: String like "INFO", "DEBUG", "ERROR" + +**Returns**: Corresponding `rdk_LogLevel` value, or `RDK_LOG_NONE` if invalid + +**Example**: +```c +rdk_LogLevel level = rdk_logger_level_from_string("DEBUG"); +if (level != RDK_LOG_NONE) { + rdk_logger_enable_logLevel("LOG.RDK.MYAPP", level, TRUE); +} +``` + +#### `rdk_logger_log_onboard()` +```c +void rdk_logger_log_onboard(const char *module, const char *msg, ...); +``` +**Purpose**: Special logging function for onboard/milestone logging. + +**Example**: +```c +rdk_logger_log_onboard("LOG.RDK.SYSTEM", "System initialization completed"); +``` + +## Configuration + +### debug.ini File Format + +The `debug.ini` file controls logging behavior for all modules: + +```ini +########################################################################## +# RDK Logger Configuration +# Format: LOG.RDK.= +########################################################################## + +# Default log level for all modules +LOG.RDK.DEFAULT=WARNING + +# Module-specific log levels +LOG.RDK.NETWORK=DEBUG # Network module: debug and above +LOG.RDK.DATABASE=INFO # Database module: info and above +LOG.RDK.SECURITY=ERROR # Security module: error and above +LOG.RDK.TESTMODULE=NONE # Test module: no logging +``` + +### Configuration Locations + +1. **Primary**: `/etc/debug.ini` +2. **Override**: `/nvram/debug.ini` (takes precedence if exists) +3. **Custom**: Specified in `rdk_logger_init()` call + +### Module Naming Convention + +- **RDK Components**: Must start with `LOG.RDK.` +- **Example**: `LOG.RDK.NETWORK`, `LOG.RDK.AUDIO`, `LOG.RDK.VIDEO` +- **Default Module**: `LOG.RDK.DEFAULT` sets the fallback level + +## Runtime Control + +### Using rdklogctrl Utility + +The `rdklogctrl` command-line utility allows runtime modification of log levels: + +```bash +# Set log level for a module +rdklogctrl + +# Examples +rdklogctrl myapp LOG.RDK.NETWORK DEBUG +rdklogctrl receiver LOG.RDK.AUDIO INFO +rdklogctrl player LOG.RDK.VIDEO ERROR + +# Disable specific log level (using ~ prefix) +rdklogctrl myapp LOG.RDK.NETWORK ~DEBUG +``` + +**Parameters**: +- `app_name`: Process name as shown by `ps` command +- `module_name`: Module name (must match debug.ini format) +- `log_level`: FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE, NONE + +### Programmatic Runtime Control + +```c +// Enable debug logging at runtime +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, TRUE); + +// Check if logging is enabled before expensive operations +if (rdk_dbg_enabled("LOG.RDK.MYAPP", RDK_LOG_TRACE)) { + generate_detailed_trace(); +} +``` + +## Log Levels + +### Available Log Levels + +| Level | Value | Description | Use Case | +|-------|-------|-------------|----------| +| `RDK_LOG_FATAL` | 0 | System unusable | Critical failures, system crash | +| `RDK_LOG_ERROR` | 1 | Error conditions | Errors that affect functionality | +| `RDK_LOG_WARN` | 2 | Warning conditions | Potential problems, degraded performance | +| `RDK_LOG_NOTICE` | 3 | Normal significant condition | Important normal events | +| `RDK_LOG_INFO` | 4 | Informational messages | General application flow | +| `RDK_LOG_DEBUG` | 5 | Debug-level messages | Detailed debugging information | +| `RDK_LOG_TRACE` | 6 | Trace-level messages | Very detailed execution tracing | +| `RDK_LOG_NONE` | 7 | No logging | Disable all logging | + +### Log Level Hierarchy + +Setting a log level enables that level and all higher priority levels: + +``` +TRACE → DEBUG → INFO → NOTICE → WARN → ERROR → FATAL +``` + +**Example**: Setting `DEBUG` enables DEBUG, INFO, NOTICE, WARN, ERROR, and FATAL messages. + +### Legacy Compatibility + +For backward compatibility with legacy RDK components: + +```c +#define RDK_LOG_TRACE1 RDK_LOG_TRACE +#define RDK_LOG_TRACE2 RDK_LOG_TRACE +// ... up to RDK_LOG_TRACE9 +``` + +## Utilities + +### rdklogctrl - Runtime Log Control + +**Location**: `utils/rdklogctrl` + +**Purpose**: Command-line utility for modifying log levels of running processes. + +**Usage**: +```bash +rdklogctrl +``` + +**Examples**: +```bash +# Enable debug logging for network module +rdklogctrl receiver LOG.RDK.NETWORK DEBUG + +# Disable all logging for test module +rdklogctrl myapp LOG.RDK.TEST NONE + +# Turn off only error logs (keep others) +rdklogctrl player LOG.RDK.AUDIO ~ERROR +``` + +### rdklogmilestone - Milestone Utility + +**Location**: `utils/rdklogmilestone.c` + +**Purpose**: C utility for milestone logging from applications. + +**Usage**: +```bash +rdklogmilestone "APPLICATION_READY" +``` + +## Examples + +### Basic Application Integration + +```c +#include +#include +#include "rdk_logger.h" + +#define MODULE_NAME "LOG.RDK.MYAPP" + +int main() { + // Initialize logger + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Failed to initialize RDK Logger\n"); + return EXIT_FAILURE; + } + + // Log application startup + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application starting up\n"); + + // Example operations with different log levels + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Initializing components\n"); + + // Conditional debug logging for performance + if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_DEBUG)) { + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug mode enabled\n"); + } + + // Simulated error condition + int error_code = 42; + if (error_code != 0) { + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, + "Operation failed with error code %d\n", error_code); + } + + // Log application shutdown + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application shutting down\n"); + + rdk_logger_deinit(); + return EXIT_SUCCESS; +} +``` + +### Network Service Example + +```c +#include "rdk_logger.h" +#include +#include + +#define NET_MODULE "LOG.RDK.NETWORK" + +int start_server(int port) { + int server_fd; + struct sockaddr_in address; + + RDK_LOG(RDK_LOG_INFO, NET_MODULE, "Starting server on port %d\n", port); + + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + RDK_LOG(RDK_LOG_ERROR, NET_MODULE, + "Failed to create socket: %s\n", strerror(errno)); + return -1; + } + + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(port); + + if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { + RDK_LOG(RDK_LOG_ERROR, NET_MODULE, + "Failed to bind to port %d: %s\n", port, strerror(errno)); + close(server_fd); + return -1; + } + + if (listen(server_fd, 10) < 0) { + RDK_LOG(RDK_LOG_ERROR, NET_MODULE, + "Failed to listen on socket: %s\n", strerror(errno)); + close(server_fd); + return -1; + } + + RDK_LOG(RDK_LOG_NOTICE, NET_MODULE, + "Server successfully started and listening on port %d\n", port); + + return server_fd; +} + +void handle_client(int client_fd, struct sockaddr_in *client_addr) { + char client_ip[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &client_addr->sin_addr, client_ip, INET_ADDRSTRLEN); + + RDK_LOG(RDK_LOG_INFO, NET_MODULE, + "New client connected from %s:%d\n", + client_ip, ntohs(client_addr->sin_port)); + + // Handle client communication... + + RDK_LOG(RDK_LOG_DEBUG, NET_MODULE, + "Processing request from %s\n", client_ip); + + // When done + RDK_LOG(RDK_LOG_INFO, NET_MODULE, + "Client %s disconnected\n", client_ip); + close(client_fd); +} +``` + +### Configuration File Example + +Create `/etc/debug.ini`: +```ini +########################################################################## +# Production Configuration +########################################################################## + +# Default level - only warnings and errors +LOG.RDK.DEFAULT=WARN + +# Network debugging enabled +LOG.RDK.NETWORK=DEBUG + +# Application flow information +LOG.RDK.MYAPP=INFO + +# Security - errors only +LOG.RDK.SECURITY=ERROR + +# Disable test modules in production +LOG.RDK.TEST=NONE +LOG.RDK.UNITTEST=NONE + +# Media components +LOG.RDK.AUDIO=NOTICE +LOG.RDK.VIDEO=NOTICE +``` + +### Wrapper Function Example + +```c +#include "rdk_logger.h" +#include + +// Custom logging wrapper with timestamp +void my_log(rdk_LogLevel level, const char *module, const char *function, + int line, const char *format, ...) { + if (!rdk_dbg_enabled(module, level)) { + return; // Early return if logging disabled + } + + va_list args; + va_start(args, format); + + // Create enhanced format with function and line info + char enhanced_format[512]; + snprintf(enhanced_format, sizeof(enhanced_format), + "[%s:%d] %s", function, line, format); + + rdk_logger_msg_vsprintf(level, module, enhanced_format, args); + va_end(args); +} + +// Convenience macro +#define MY_LOG(level, module, format, ...) \ + my_log(level, module, __FUNCTION__, __LINE__, format, ##__VA_ARGS__) + +// Usage +int main() { + RDK_LOGGER_INIT(); + + MY_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Application started\n"); + MY_LOG(RDK_LOG_DEBUG, "LOG.RDK.MYAPP", "Variable value: %d\n", 42); + + rdk_logger_deinit(); + return 0; +} +``` + +## Error Handling + +### Return Codes + +All initialization functions return `rdk_Error` type: + +```c +typedef uint32_t rdk_Error; +#define RDK_SUCCESS 0 +``` + +**Common Error Scenarios**: +- Configuration file not found +- Invalid configuration format +- Memory allocation failures +- Log4C initialization errors + +### Error Handling Pattern + +```c +rdk_Error init_logging(const char *config_file) { + rdk_Error ret = rdk_logger_init(config_file); + if (ret != RDK_SUCCESS) { + fprintf(stderr, "Logger initialization failed: %u\n", ret); + fprintf(stderr, "Falling back to stdout logging\n"); + // Implement fallback logging mechanism + return ret; + } + return RDK_SUCCESS; +} +``` + +### Graceful Degradation + +```c +int main() { + // Try to initialize logger + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Warning: RDK Logger initialization failed\n"); + fprintf(stderr, "Continuing with fprintf logging\n"); + + // Application can continue with basic printf/fprintf + printf("Application started (no RDK logging)\n"); + } else { + RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.MYAPP", "Application started\n"); + } + + // Rest of application... + + return 0; +} +``` + +## Best Practices + +### 1. Module Naming +```c +// Good - descriptive and consistent +#define AUDIO_MODULE "LOG.RDK.AUDIO" +#define NETWORK_MODULE "LOG.RDK.NETWORK" +#define DATABASE_MODULE "LOG.RDK.DATABASE" + +// Avoid - generic or unclear names +#define MODULE "LOG.RDK.APP" +#define MY_MODULE "LOG.RDK.THING" +``` + +### 2. Performance Optimization +```c +// Check if logging is enabled before expensive operations +if (rdk_dbg_enabled("LOG.RDK.MYAPP", RDK_LOG_DEBUG)) { + char *expensive_debug_info = generate_debug_dump(); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.MYAPP", "Debug: %s\n", expensive_debug_info); + free(expensive_debug_info); +} + +// Use appropriate log levels +RDK_LOG(RDK_LOG_FATAL, module, "System crash: %s\n", reason); // System unusable +RDK_LOG(RDK_LOG_ERROR, module, "Failed to connect: %s\n", err); // Error conditions +RDK_LOG(RDK_LOG_WARN, module, "Retrying connection\n"); // Warnings +RDK_LOG(RDK_LOG_NOTICE, module, "Service started\n"); // Important events +RDK_LOG(RDK_LOG_INFO, module, "Processing request\n"); // General info +RDK_LOG(RDK_LOG_DEBUG, module, "Variable x = %d\n", x); // Debug details +RDK_LOG(RDK_LOG_TRACE, module, "Entering function\n"); // Function tracing +``` + +### 3. Thread Safety +```c +// RDK Logger is thread-safe, but avoid race conditions in your logic +void worker_thread(void *arg) { + int thread_id = *(int*)arg; + + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.WORKER", + "Worker thread %d started\n", thread_id); + + // Worker logic... + + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.WORKER", + "Worker thread %d finished\n", thread_id); +} +``` + +### 4. Configuration Management +```c +// Check for override config file +const char* get_config_file() { + if (access("/nvram/debug.ini", F_OK) == 0) { + return "/nvram/debug.ini"; // Development/debug config + } + return "/etc/debug.ini"; // Production config +} + +// Initialize with appropriate config +rdk_Error ret = rdk_logger_init(get_config_file()); +``` + +### 5. Structured Logging +```c +// Include relevant context in log messages +RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.NETWORK", + "Connection failed: host=%s, port=%d, error=%s\n", + hostname, port, strerror(errno)); + +// Use consistent formats for similar events +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.SERVICE", + "SERVICE_START: name=%s, pid=%d, version=%s\n", + service_name, getpid(), version); +``` + +### 6. Cleanup +```c +// Always clean up in signal handlers and exit paths +void signal_handler(int sig) { + RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.MYAPP", + "Received signal %d, shutting down\n", sig); + rdk_logger_deinit(); + exit(0); +} + +int main() { + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + + RDK_LOGGER_INIT(); + + // Application logic... + + rdk_logger_deinit(); + return 0; +} +``` + +--- + +**Note**: This documentation covers RDK Logger API version as implemented in the current codebase. For the most up-to-date information, refer to the source code and header files. + diff --git a/docs/MIGRATION_GUIDE.md b/docs/MIGRATION_GUIDE.md new file mode 100644 index 0000000..9f72735 --- /dev/null +++ b/docs/MIGRATION_GUIDE.md @@ -0,0 +1,363 @@ +# RDK Logger Migration Guide + +## Overview + +This guide helps developers migrate from other logging systems to RDK Logger and upgrade existing RDK Logger implementations. + +## Migration from printf/fprintf + +### Before (Legacy Code) +```c +#include + +int main() { + printf("Application started\n"); + fprintf(stderr, "Error: Connection failed\n"); + printf("Debug: value = %d\n", value); + return 0; +} +``` + +### After (RDK Logger) +```c +#include "rdk_logger.h" + +#define MODULE_NAME "LOG.RDK.MYAPP" + +int main() { + // Initialize logger + RDK_LOGGER_INIT(); + + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application started\n"); + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, "Error: Connection failed\n"); + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug: value = %d\n", value); + + rdk_logger_deinit(); + return 0; +} +``` + +## Migration from syslog + +### Before (syslog) +```c +#include + +int main() { + openlog("myapp", LOG_PID, LOG_USER); + + syslog(LOG_INFO, "Application started"); + syslog(LOG_ERR, "Connection failed: %s", strerror(errno)); + syslog(LOG_DEBUG, "Processing item %d", item_id); + + closelog(); + return 0; +} +``` + +### After (RDK Logger) +```c +#include "rdk_logger.h" + +#define MODULE_NAME "LOG.RDK.MYAPP" + +int main() { + RDK_LOGGER_INIT(); + + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Application started\n"); + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, "Connection failed: %s\n", strerror(errno)); + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Processing item %d\n", item_id); + + rdk_logger_deinit(); + return 0; +} +``` + +### Log Level Mapping + +| syslog Level | RDK Logger Level | Description | +|--------------|------------------|-------------| +| LOG_EMERG | RDK_LOG_FATAL | System unusable | +| LOG_ALERT | RDK_LOG_FATAL | Action must be taken immediately | +| LOG_CRIT | RDK_LOG_FATAL | Critical conditions | +| LOG_ERR | RDK_LOG_ERROR | Error conditions | +| LOG_WARNING | RDK_LOG_WARN | Warning conditions | +| LOG_NOTICE | RDK_LOG_NOTICE | Normal but significant condition | +| LOG_INFO | RDK_LOG_INFO | Informational messages | +| LOG_DEBUG | RDK_LOG_DEBUG | Debug-level messages | + +## Migration from Custom Logging + +### Wrapper Approach +If you have existing custom logging macros, you can create wrapper functions: + +```c +// Legacy logging system +#define OLD_LOG_ERROR(fmt, ...) old_log_function(ERROR_LEVEL, fmt, ##__VA_ARGS__) +#define OLD_LOG_INFO(fmt, ...) old_log_function(INFO_LEVEL, fmt, ##__VA_ARGS__) + +// Migration wrapper +#define LOG_ERROR(fmt, ...) RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, fmt, ##__VA_ARGS__) +#define LOG_INFO(fmt, ...) RDK_LOG(RDK_LOG_INFO, MODULE_NAME, fmt, ##__VA_ARGS__) + +// Now replace OLD_LOG_* with LOG_* throughout your codebase +``` + +### Gradual Migration +You can run both systems in parallel during migration: + +```c +#include "rdk_logger.h" +#include "old_logger.h" + +#define DUAL_LOG(level, old_level, fmt, ...) do { \ + RDK_LOG(level, MODULE_NAME, fmt, ##__VA_ARGS__); \ + old_log_function(old_level, fmt, ##__VA_ARGS__); \ +} while(0) + +// Use DUAL_LOG during migration, then switch to RDK_LOG +``` + +## Configuration Migration + +### Converting Log Levels +Create a migration script to convert existing configuration: + +```bash +#!/bin/bash +# migrate_config.sh + +# Convert old format to debug.ini format +old_config="/etc/old_logger.conf" +new_config="/etc/debug.ini" + +echo "# Migrated configuration" > $new_config +echo "LOG.RDK.DEFAULT=WARNING" >> $new_config + +# Parse old configuration and convert +while IFS='=' read -r module level; do + case $level in + "error") new_level="ERROR" ;; + "warning") new_level="WARN" ;; + "info") new_level="INFO" ;; + "debug") new_level="DEBUG" ;; + *) new_level="NOTICE" ;; + esac + echo "LOG.RDK.$module=$new_level" >> $new_config +done < $old_config +``` + +## Advanced Migration Patterns + +### Conditional Compilation +Support both old and new logging during transition: + +```c +#ifdef USE_RDK_LOGGER + #include "rdk_logger.h" + #define APP_LOG(level, fmt, ...) RDK_LOG(level, MODULE_NAME, fmt, ##__VA_ARGS__) + #define APP_LOG_INIT() RDK_LOGGER_INIT() + #define APP_LOG_CLEANUP() rdk_logger_deinit() +#else + #include "old_logger.h" + #define APP_LOG(level, fmt, ...) old_log(level, fmt, ##__VA_ARGS__) + #define APP_LOG_INIT() old_log_init() + #define APP_LOG_CLEANUP() old_log_cleanup() +#endif + +int main() { + APP_LOG_INIT(); + APP_LOG(RDK_LOG_INFO, "Application started\n"); + // ... application code ... + APP_LOG_CLEANUP(); + return 0; +} +``` + +### Performance Comparison +Test performance impact during migration: + +```c +#include + +void performance_test() { + clock_t start, end; + int iterations = 10000; + + // Test RDK Logger performance + start = clock(); + for (int i = 0; i < iterations; i++) { + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Test message %d\n", i); + } + end = clock(); + + double rdk_time = ((double)(end - start)) / CLOCKS_PER_SEC; + printf("RDK Logger: %f seconds for %d messages\n", rdk_time, iterations); +} +``` + +## Common Migration Issues + +### Issue 1: Missing Newlines +**Problem**: RDK Logger expects newlines in format strings. +```c +// Wrong +RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Message"); + +// Correct +RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Message\n"); +``` + +### Issue 2: Module Name Format +**Problem**: Incorrect module naming convention. +```c +// Wrong +RDK_LOG(RDK_LOG_INFO, "MYAPP", "Message\n"); + +// Correct +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Message\n"); +``` + +### Issue 3: Initialization Order +**Problem**: Logging before initialization. +```c +// Wrong +int main() { + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Starting\n"); // Will fail + RDK_LOGGER_INIT(); +} + +// Correct +int main() { + RDK_LOGGER_INIT(); + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Starting\n"); +} +``` + +### Issue 4: Thread Safety +**Problem**: Initialization in multi-threaded environment. +```c +// Wrong - race condition +void thread_function() { + RDK_LOGGER_INIT(); // Multiple threads calling init + // ... +} + +// Correct - initialize once in main thread +int main() { + RDK_LOGGER_INIT(); + + // Create threads after initialization + pthread_create(&thread, NULL, thread_function, NULL); +} +``` + +## Testing Migration + +### Validation Script +```bash +#!/bin/bash +# validate_migration.sh + +echo "Testing RDK Logger migration..." + +# Test 1: Configuration file exists +if [ ! -f /etc/debug.ini ]; then + echo "ERROR: debug.ini not found" + exit 1 +fi + +# Test 2: Module names follow convention +if ! grep -q "LOG.RDK." /etc/debug.ini; then + echo "WARNING: No LOG.RDK modules found in config" +fi + +# Test 3: Test application logging +./test_app > /tmp/test_output.log 2>&1 + +if grep -q "LOG.RDK" /tmp/test_output.log; then + echo "SUCCESS: RDK Logger output detected" +else + echo "ERROR: No RDK Logger output found" + exit 1 +fi + +echo "Migration validation complete" +``` + +### Unit Test Example +```c +#include +#include "rdk_logger.h" + +void test_migration() { + // Test initialization + assert(RDK_LOGGER_INIT() == RDK_SUCCESS); + + // Test logging levels + assert(rdk_dbg_enabled("LOG.RDK.TEST", RDK_LOG_ERROR) == TRUE); + + // Test cleanup + assert(rdk_logger_deinit() == RDK_SUCCESS); + + printf("Migration tests passed\n"); +} +``` + +## Migration Checklist + +- [ ] Review existing logging calls and categorize by log level +- [ ] Create module name mapping (old names → LOG.RDK.* names) +- [ ] Update configuration files to debug.ini format +- [ ] Replace logging function calls with RDK_LOG macros +- [ ] Add RDK_LOGGER_INIT() and rdk_logger_deinit() calls +- [ ] Update build system to link RDK Logger libraries +- [ ] Test logging output and configuration +- [ ] Validate runtime log level changes work +- [ ] Update documentation and deployment scripts +- [ ] Train team on new logging system usage + +## Post-Migration Optimization + +### 1. Performance Tuning +```c +// Use conditional logging for expensive debug operations +if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_DEBUG)) { + char *debug_dump = expensive_debug_function(); + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug: %s\n", debug_dump); + free(debug_dump); +} +``` + +### 2. Configuration Optimization +```ini +# Production config - minimal logging +LOG.RDK.DEFAULT=ERROR + +# Development config - detailed logging +LOG.RDK.DEFAULT=DEBUG +LOG.RDK.NETWORK=TRACE +LOG.RDK.DATABASE=DEBUG +``` + +### 3. Monitoring Integration +```c +// Add metrics for log message rates +void log_with_metrics(rdk_LogLevel level, const char *module, + const char *format, ...) { + static int log_count = 0; + log_count++; + + if (log_count % 1000 == 0) { + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.METRICS", + "Logged %d messages\n", log_count); + } + + va_list args; + va_start(args, format); + rdk_logger_msg_vsprintf(level, module, format, args); + va_end(args); +} +``` + +This migration guide provides a comprehensive approach to transitioning to RDK Logger while maintaining system stability and performance. \ No newline at end of file diff --git a/docs/QUICK_REFERENCE.md b/docs/QUICK_REFERENCE.md new file mode 100644 index 0000000..d2ab5d3 --- /dev/null +++ b/docs/QUICK_REFERENCE.md @@ -0,0 +1,336 @@ +# RDK Logger Quick Reference + +## Essential Functions + +### Initialization +```c +#include "rdk_logger.h" + +// Standard initialization (uses /etc/debug.ini or /nvram/debug.ini) +RDK_LOGGER_INIT(); + +// Custom config file +rdk_logger_init("/path/to/custom/debug.ini"); + +// Extended initialization with file logging +rdk_logger_ext_config_t config = { + .fileName = "app.log", + .logdir = "/var/log/", + .maxSize = 1024*1024, // 1MB + .maxCount = 5 // Keep 5 files +}; +rdk_logger_ext_init(&config); + +// Cleanup +rdk_logger_deinit(); +``` + +### Logging +```c +// Basic logging +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Message\n"); + +// Formatted logging +RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.MYAPP", "Error %d: %s\n", errno, strerror(errno)); + +// Performance-conscious logging +if (rdk_dbg_enabled("LOG.RDK.MYAPP", RDK_LOG_DEBUG)) { + char *expensive_data = generate_debug_info(); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.MYAPP", "Debug: %s\n", expensive_data); + free(expensive_data); +} +``` + +## Log Levels (Priority Order) + +| Level | Macro | When to Use | +|-------|-------|-------------| +| FATAL | `RDK_LOG_FATAL` | System crash, unusable | +| ERROR | `RDK_LOG_ERROR` | Operation failures | +| WARN | `RDK_LOG_WARN` | Potential problems | +| NOTICE| `RDK_LOG_NOTICE` | Important events | +| INFO | `RDK_LOG_INFO` | General information | +| DEBUG | `RDK_LOG_DEBUG` | Debugging details | +| TRACE | `RDK_LOG_TRACE` | Function tracing | + +## Configuration (debug.ini) + +```ini +# Default level for all modules +LOG.RDK.DEFAULT=WARNING + +# Module-specific levels +LOG.RDK.NETWORK=DEBUG +LOG.RDK.AUDIO=INFO +LOG.RDK.VIDEO=NOTICE +LOG.RDK.TEST=NONE +``` + +### Config File Locations (Priority Order) +1. `/nvram/debug.ini` (override - highest priority) +2. `/etc/debug.ini` (default) +3. Custom path via `rdk_logger_init(path)` + +## Runtime Control + +### rdklogctrl Command +```bash +# Set log level for module +rdklogctrl + +# Examples +rdklogctrl myapp LOG.RDK.NETWORK DEBUG +rdklogctrl receiver LOG.RDK.AUDIO INFO +rdklogctrl player LOG.RDK.VIDEO ERROR + +# Disable specific level (~ prefix) +rdklogctrl myapp LOG.RDK.NETWORK ~DEBUG + +# Available levels +FATAL ERROR WARN NOTICE INFO DEBUG TRACE NONE +``` + +### Programmatic Control +```c +// Check if level is enabled +if (rdk_dbg_enabled("LOG.RDK.MYAPP", RDK_LOG_DEBUG)) { + // Debug logging is enabled +} + +// Enable/disable level at runtime +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, TRUE); // Enable +rdk_logger_enable_logLevel("LOG.RDK.MYAPP", RDK_LOG_DEBUG, FALSE); // Disable + +// Convert string to log level +rdk_LogLevel level = rdk_logger_level_from_string("INFO"); +``` + +## Module Naming Convention + +### Correct Format +```c +#define MODULE_NAME "LOG.RDK.MYAPP" +#define NETWORK_MODULE "LOG.RDK.NETWORK" +#define AUDIO_MODULE "LOG.RDK.AUDIO" +``` + +### Common Mistakes +```c +// ❌ Wrong - missing LOG.RDK prefix +RDK_LOG(RDK_LOG_INFO, "MYAPP", "Message\n"); + +// ❌ Wrong - case sensitivity +RDK_LOG(RDK_LOG_INFO, "log.rdk.myapp", "Message\n"); + +// ❌ Wrong - extra spaces +RDK_LOG(RDK_LOG_INFO, "LOG.RDK. MYAPP", "Message\n"); + +// ✅ Correct +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Message\n"); +``` + +## Common Patterns + +### Application Template +```c +#include "rdk_logger.h" +#include + +#define MODULE_NAME "LOG.RDK.MYAPP" + +void cleanup_handler(int sig) { + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Shutting down (signal %d)\n", sig); + rdk_logger_deinit(); + exit(0); +} + +int main() { + // Setup signal handlers + signal(SIGTERM, cleanup_handler); + signal(SIGINT, cleanup_handler); + + // Initialize logger + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + fprintf(stderr, "Logger init failed\n"); + return 1; + } + + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application started\n"); + + // Main application logic + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Processing...\n"); + + // Cleanup + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, "Application finished\n"); + rdk_logger_deinit(); + return 0; +} +``` + +### Error Handling Pattern +```c +int connect_to_server(const char *hostname, int port) { + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Connecting to %s:%d\n", hostname, port); + + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, + "Socket creation failed: %s\n", strerror(errno)); + return -1; + } + + // Connection logic... + + if (connect_result < 0) { + RDK_LOG(RDK_LOG_ERROR, MODULE_NAME, + "Connection to %s:%d failed: %s\n", + hostname, port, strerror(errno)); + close(sock); + return -1; + } + + RDK_LOG(RDK_LOG_NOTICE, MODULE_NAME, + "Successfully connected to %s:%d\n", hostname, port); + return sock; +} +``` + +### Performance-Conscious Logging +```c +void process_data(const data_t *data) { + RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Processing data batch\n"); + + // Only generate expensive debug info if debug logging is enabled + if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_DEBUG)) { + char debug_info[1024]; + generate_debug_summary(data, debug_info, sizeof(debug_info)); + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Data details: %s\n", debug_info); + } + + // Trace function entry/exit only if trace is enabled + if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_TRACE)) { + RDK_LOG(RDK_LOG_TRACE, MODULE_NAME, "Entering %s\n", __FUNCTION__); + } + + // Process data... + + if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_TRACE)) { + RDK_LOG(RDK_LOG_TRACE, MODULE_NAME, "Exiting %s\n", __FUNCTION__); + } +} +``` + +## Build Integration + +### Makefile +```makefile +# Compiler flags +CFLAGS += -I/usr/include/rdklogger + +# Linker flags +LDFLAGS += -lrdkloggers -llog4c -lglib-2.0 + +# Example target +myapp: myapp.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) +``` + +### CMake +```cmake +# Find required libraries +find_package(PkgConfig REQUIRED) +pkg_check_modules(GLIB REQUIRED glib-2.0) + +# Link libraries +target_link_libraries(myapp + rdkloggers + log4c + ${GLIB_LIBRARIES} +) + +# Include directories +target_include_directories(myapp PRIVATE + /usr/include/rdklogger + ${GLIB_INCLUDE_DIRS} +) +``` + +## Debugging Tips + +### Check Configuration +```bash +# Verify config file exists and is readable +cat /etc/debug.ini + +# Test with specific module +grep "LOG.RDK.MYAPP" /etc/debug.ini + +# Check default level +grep "LOG.RDK.DEFAULT" /etc/debug.ini +``` + +### Test Logging +```c +// Test program to verify logging works +#include "rdk_logger.h" + +int main() { + printf("Testing RDK Logger...\n"); + + if (RDK_LOGGER_INIT() != RDK_SUCCESS) { + printf("❌ Init failed\n"); + return 1; + } + printf("✅ Init succeeded\n"); + + const char *module = "LOG.RDK.TEST"; + + printf("Testing log levels:\n"); + RDK_LOG(RDK_LOG_FATAL, module, "❌ FATAL message\n"); + RDK_LOG(RDK_LOG_ERROR, module, "🔴 ERROR message\n"); + RDK_LOG(RDK_LOG_WARN, module, "🟡 WARN message\n"); + RDK_LOG(RDK_LOG_NOTICE, module, "🔵 NOTICE message\n"); + RDK_LOG(RDK_LOG_INFO, module, "ℹ️ INFO message\n"); + RDK_LOG(RDK_LOG_DEBUG, module, "🐛 DEBUG message\n"); + RDK_LOG(RDK_LOG_TRACE, module, "🔍 TRACE message\n"); + + rdk_logger_deinit(); + printf("✅ Test completed\n"); + return 0; +} +``` + +### Runtime Control Test +```bash +# Start your application in background +./myapp & +APP_PID=$! + +# Change log level +rdklogctrl myapp LOG.RDK.TEST DEBUG + +# Check if change took effect (application should show more logs) + +# Cleanup +kill $APP_PID +``` + +## Error Codes + +| Code | Meaning | Action | +|------|---------|---------| +| 0 | `RDK_SUCCESS` | Operation successful | +| Non-zero | Various errors | Check config file, permissions, dependencies | + +## Dependencies + +### Required Libraries +- `librdkloggers` - RDK Logger library +- `liblog4c` - Log4C logging framework +- `libglib-2.0` - GLib utility library + +### Optional Tools +- `rdklogctrl` - Runtime log control utility +- `rdklogmilestone` - Milestone logging utility + +This quick reference provides the most commonly needed information for day-to-day RDK Logger usage. \ No newline at end of file diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md new file mode 100644 index 0000000..259fb52 --- /dev/null +++ b/docs/TROUBLESHOOTING.md @@ -0,0 +1,514 @@ +# RDK Logger Troubleshooting Guide + +## Common Issues and Solutions + +### 1. Logger Initialization Failures + +#### Issue: `rdk_logger_init()` returns error +**Symptoms:** +``` +Logger initialization failed with return: -1 +config_file ini is not found +``` + +**Causes and Solutions:** + +**Cause 1: Configuration file not found** +```bash +# Check if config file exists +ls -la /etc/debug.ini +ls -la /nvram/debug.ini +``` + +**Solution:** +```bash +# Create default configuration +sudo cp debug.ini.sample /etc/debug.ini +sudo chmod 644 /etc/debug.ini +``` + +**Cause 2: Permission issues** +```bash +# Check file permissions +ls -la /etc/debug.ini +``` + +**Solution:** +```bash +# Fix permissions +sudo chown root:root /etc/debug.ini +sudo chmod 644 /etc/debug.ini +``` + +**Cause 3: Invalid configuration format** +```ini +# Wrong format +INVALID.FORMAT=DEBUG + +# Correct format +LOG.RDK.MYAPP=DEBUG +``` + +#### Issue: Multiple initialization calls +**Problem:** +```c +// This can cause issues +RDK_LOGGER_INIT(); +RDK_LOGGER_INIT(); // Second call may fail +``` + +**Solution:** +```c +static int logger_initialized = 0; + +int init_logger_once() { + if (!logger_initialized) { + if (RDK_LOGGER_INIT() == RDK_SUCCESS) { + logger_initialized = 1; + return 0; + } + return -1; + } + return 0; // Already initialized +} +``` + +### 2. No Log Output + +#### Issue: Messages not appearing despite configuration + +**Debugging Steps:** + +**Step 1: Verify initialization** +```c +#include "rdk_logger.h" + +int main() { + printf("Before RDK_LOGGER_INIT\n"); + rdk_Error ret = RDK_LOGGER_INIT(); + printf("RDK_LOGGER_INIT returned: %d\n", ret); + + printf("Testing log output...\n"); + RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.TEST", "Test error message\n"); + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.TEST", "Test info message\n"); + + rdk_logger_deinit(); + return 0; +} +``` + +**Step 2: Check configuration** +```bash +# Verify config file content +cat /etc/debug.ini + +# Check for your module +grep "LOG.RDK.TEST" /etc/debug.ini + +# Check default level +grep "LOG.RDK.DEFAULT" /etc/debug.ini +``` + +**Step 3: Test log level checking** +```c +// Debug log level checking +const char *module = "LOG.RDK.TEST"; +printf("ERROR enabled: %d\n", rdk_dbg_enabled(module, RDK_LOG_ERROR)); +printf("WARN enabled: %d\n", rdk_dbg_enabled(module, RDK_LOG_WARN)); +printf("INFO enabled: %d\n", rdk_dbg_enabled(module, RDK_LOG_INFO)); +printf("DEBUG enabled: %d\n", rdk_dbg_enabled(module, RDK_LOG_DEBUG)); +``` + +**Step 4: Check environment** +```bash +# Verify log4c is available +ldd your_application | grep log4c + +# Check if log4c config exists +find /etc -name "*log4c*" 2>/dev/null +``` + +### 3. Runtime Log Control Issues + +#### Issue: `rdklogctrl` not working + +**Problem:** Changes don't take effect +```bash +# Command appears to work but no change +rdklogctrl myapp LOG.RDK.NETWORK DEBUG +``` + +**Debugging:** + +**Step 1: Verify process name** +```bash +# Check exact process name +ps aux | grep myapp + +# Use exact name from ps output +rdklogctrl "myapp_process_name" LOG.RDK.NETWORK DEBUG +``` + +**Step 2: Check process accessibility** +```bash +# Verify process is running as expected user +ps -ef | grep myapp + +# Check if process accepts socket connections +netstat -tlnp | grep :12035 +``` + +**Step 3: Test with simple module** +```bash +# Try with a known module first +rdklogctrl myapp LOG.RDK.DEFAULT INFO +``` + +#### Issue: Dynamic logging not persistent +**Problem:** Log level changes revert after application restart + +**Explanation:** `rdklogctrl` changes are runtime-only. For persistent changes, modify `debug.ini`: + +```bash +# For persistent changes +sudo nano /etc/debug.ini + +# Add or modify +LOG.RDK.NETWORK=DEBUG +``` + +### 4. Performance Issues + +#### Issue: Logging causing performance degradation + +**Problem:** Application becomes slow when debug logging is enabled + +**Solution 1: Conditional logging** +```c +// Wrong - always evaluates expensive_function() +RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug: %s\n", expensive_function()); + +// Right - only calls expensive_function() if debug is enabled +if (rdk_dbg_enabled(MODULE_NAME, RDK_LOG_DEBUG)) { + RDK_LOG(RDK_LOG_DEBUG, MODULE_NAME, "Debug: %s\n", expensive_function()); +} +``` + +**Solution 2: Optimize log levels** +```ini +# Production config - minimal logging +LOG.RDK.DEFAULT=ERROR +LOG.RDK.CRITICAL_MODULE=WARN + +# Only enable debug for specific investigation +LOG.RDK.PROBLEM_MODULE=DEBUG +``` + +**Solution 3: Measure logging overhead** +```c +#include + +void measure_logging_performance() { + clock_t start = clock(); + + for (int i = 0; i < 10000; i++) { + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.PERF", "Test message %d\n", i); + } + + clock_t end = clock(); + double time_spent = ((double)(end - start)) / CLOCKS_PER_SEC; + + printf("10000 log messages took %f seconds\n", time_spent); +} +``` + +### 5. Memory Issues + +#### Issue: Memory leaks or crashes + +**Problem:** Application crashes or shows memory leaks related to logging + +**Solution 1: Proper cleanup** +```c +#include + +void cleanup_handler(int sig) { + RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.MAIN", "Received signal %d, cleaning up\n", sig); + rdk_logger_deinit(); + exit(0); +} + +int main() { + // Register signal handlers + signal(SIGTERM, cleanup_handler); + signal(SIGINT, cleanup_handler); + + RDK_LOGGER_INIT(); + + // Application logic... + + rdk_logger_deinit(); + return 0; +} +``` + +**Solution 2: Check for double-free issues** +```c +// Avoid static string modification +char buffer[256]; +snprintf(buffer, sizeof(buffer), "Dynamic message: %d", value); +RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "%s\n", buffer); +``` + +**Solution 3: Valgrind debugging** +```bash +# Run with valgrind to detect memory issues +valgrind --leak-check=full --show-leak-kinds=all ./your_app + +# Look for leaks in librdkloggers or liblog4c +``` + +### 6. Multi-threading Issues + +#### Issue: Garbled log output or crashes in multi-threaded applications + +**Problem:** Multiple threads logging simultaneously causing corruption + +**Solution 1: RDK Logger is thread-safe (internal synchronization)** +```c +#include + +void* worker_thread(void* arg) { + int thread_id = *(int*)arg; + + // This is safe - RDK Logger handles synchronization + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.WORKER", + "Thread %d: Starting work\n", thread_id); + + // Do work... + + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.WORKER", + "Thread %d: Work completed\n", thread_id); + + return NULL; +} +``` + +**Solution 2: If issues persist, add application-level synchronization** +```c +#include + +static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define SAFE_LOG(level, module, format, ...) do { \ + pthread_mutex_lock(&log_mutex); \ + RDK_LOG(level, module, format, ##__VA_ARGS__); \ + pthread_mutex_unlock(&log_mutex); \ +} while(0) +``` + +### 7. Configuration Issues + +#### Issue: Module-specific settings not working + +**Problem:** Settings in debug.ini not taking effect for specific modules + +**Debug steps:** + +**Step 1: Verify module name format** +```ini +# Wrong formats +MYAPP=DEBUG # Missing LOG.RDK prefix +LOG.RDK.MyApp=DEBUG # Case sensitive +LOG.RDK. MYAPP=DEBUG # Extra space + +# Correct format +LOG.RDK.MYAPP=DEBUG +``` + +**Step 2: Check for syntax errors** +```bash +# Validate config file syntax +grep -n "=" /etc/debug.ini | grep -v "^#" + +# Check for invalid characters +hexdump -C /etc/debug.ini | head -20 +``` + +**Step 3: Test with minimal config** +```ini +# Minimal test config +LOG.RDK.DEFAULT=INFO +LOG.RDK.TEST=DEBUG +``` + +#### Issue: Case sensitivity problems + +**Problem:** Module names not matching due to case differences + +```c +// These are different modules +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MyApp", "Message\n"); // MyApp +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.MYAPP", "Message\n"); // MYAPP +RDK_LOG(RDK_LOG_INFO, "LOG.RDK.myapp", "Message\n"); // myapp +``` + +**Solution:** Use consistent naming convention +```c +// Define module name once +#define MODULE_NAME "LOG.RDK.MYAPP" + +// Use throughout application +RDK_LOG(RDK_LOG_INFO, MODULE_NAME, "Message\n"); +``` + +### 8. Build and Linking Issues + +#### Issue: Undefined references during compilation + +**Problem:** +``` +undefined reference to `rdk_logger_init' +undefined reference to `rdk_logger_msg_printf' +``` + +**Solution 1: Check linking order** +```bash +# Wrong order +gcc -lrdkloggers myapp.c -llog4c -lglib-2.0 + +# Correct order +gcc myapp.c -lrdkloggers -llog4c -lglib-2.0 +``` + +**Solution 2: Verify library installation** +```bash +# Check if libraries are installed +ldconfig -p | grep rdkloggers +ldconfig -p | grep log4c + +# Find library files +find /usr -name "librdkloggers*" 2>/dev/null +find /usr -name "liblog4c*" 2>/dev/null +``` + +**Solution 3: Use pkg-config if available** +```bash +# Check for pkg-config files +pkg-config --list-all | grep rdk + +# If available, use pkg-config +gcc myapp.c `pkg-config --cflags --libs rdklogger` +``` + +### 9. Log File Issues + +#### Issue: Log files not being created or rotated + +**Problem:** Using `rdk_logger_ext_init()` but files not appearing + +**Debug steps:** + +**Step 1: Check directory permissions** +```c +rdk_logger_ext_config_t config = { + .fileName = "myapp.log", + .logdir = "/var/log/", // Check if writable + .maxSize = 1024 * 1024, + .maxCount = 5 +}; + +// Test directory access +if (access("/var/log/", W_OK) != 0) { + perror("Cannot write to /var/log/"); +} +``` + +**Step 2: Use accessible directory** +```c +rdk_logger_ext_config_t config = { + .fileName = "myapp.log", + .logdir = "/tmp/", // Use /tmp for testing + .maxSize = 1024 * 1024, + .maxCount = 5 +}; +``` + +**Step 3: Check log4c configuration** +```bash +# Look for log4c config files +find /etc -name "*log4c*" 2>/dev/null + +# Check log4c configuration +export LOG4C_APPENDER_FILE_FILENAME="/tmp/test.log" +./your_app +``` + +### 10. Debugging Tools and Techniques + +#### Environment Variables +```bash +# Enable log4c debugging +export LOG4C_PRIORITY=debug +export LOG4C_APPENDER=stdout + +# Run your application +./your_app +``` + +#### Debugging Configuration Loading +```c +#include "rdk_logger.h" + +void debug_config_loading() { + printf("Checking config files:\n"); + + // Check primary config + if (access("/etc/debug.ini", F_OK) == 0) { + printf("✓ /etc/debug.ini exists\n"); + } else { + printf("✗ /etc/debug.ini not found\n"); + } + + // Check override config + if (access("/nvram/debug.ini", F_OK) == 0) { + printf("✓ /nvram/debug.ini exists (will be used)\n"); + } else { + printf("✗ /nvram/debug.ini not found\n"); + } + + // Test initialization + rdk_Error ret = RDK_LOGGER_INIT(); + printf("Logger init result: %d (%s)\n", ret, + ret == RDK_SUCCESS ? "SUCCESS" : "FAILED"); +} +``` + +#### Network Debugging for rdklogctrl +```bash +# Check if dynamic logger port is listening +netstat -tlnp | grep :12035 + +# Test socket connection +telnet localhost 12035 + +# Monitor network traffic +tcpdump -i lo port 12035 +``` + +### Quick Reference Checklist + +When troubleshooting RDK Logger issues: + +1. **✓ Check configuration file exists and is readable** +2. **✓ Verify module names follow LOG.RDK.* convention** +3. **✓ Confirm logger initialization succeeded** +4. **✓ Test with simple log levels (ERROR, INFO)** +5. **✓ Check process name for rdklogctrl commands** +6. **✓ Verify library linking is correct** +7. **✓ Test with minimal configuration** +8. **✓ Check file permissions for log directories** +9. **✓ Use debugging tools (valgrind, gdb, strace)** +10. **✓ Enable log4c debugging if needed** + +This troubleshooting guide should help resolve most common issues with RDK Logger implementation and usage. \ No newline at end of file diff --git a/include/rdk_logger.h b/include/rdk_logger.h index a17a496..12cb3ba 100644 --- a/include/rdk_logger.h +++ b/include/rdk_logger.h @@ -76,13 +76,6 @@ * * @image html rdk_logger_architecture.jpg * - * @par RDK Logging Configuration - * @n Default level of logging is WARNING. Logging settings can be overriden by debug.ini - * @code - * - LOG.RDK. = INFO - * - LOG.RDK. = DEBUG - * @endcode - * * @par Logging Levels supported by RDK Logger. * Code | Description * -----|------------ From 92065f0e648feb9fa2f696c77ec88560ae349fbd Mon Sep 17 00:00:00 2001 From: kamirt573_comcast Date: Tue, 23 Sep 2025 18:23:37 +0000 Subject: [PATCH 20/37] Release of RDKLogger v2.3.0 Release of v2.3.0 Signed-off-by: kamirt573_comcast --- CHANGELOG.md | 8 ++++++++ configure.ac | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfbabf0..6309d4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,17 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v2.3.0](https://github.com/rdkcentral/rdk_logger/compare/v2.2.0...v2.3.0) + +- Update Documentation for RDKLogger [`#24`](https://github.com/rdkcentral/rdk_logger/pull/24) +- RDKB-61752 : Add Legacy Function for Backward Compatibility [`#23`](https://github.com/rdkcentral/rdk_logger/pull/23) + #### [v2.2.0](https://github.com/rdkcentral/rdk_logger/compare/v2.1.0...v2.2.0) +> 8 September 2025 + - [RDKC-16005]: RDKLogger OpenSource Migration [`#21`](https://github.com/rdkcentral/rdk_logger/pull/21) +- Release of RDKLogger v2.2.0 [`28d277a`](https://github.com/rdkcentral/rdk_logger/commit/28d277ae00b0f6fdaae1e8c263706efed9651087) #### [v2.1.0](https://github.com/rdkcentral/rdk_logger/compare/v2.0.0...v2.1.0) diff --git a/configure.ac b/configure.ac index 2ce7b77..ae73e34 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 2.2.0) +AC_INIT(rdklogger, 2.3.0) AC_CONFIG_SRCDIR([src]) AM_CONFIG_HEADER(cfg/config.h) AC_CONFIG_MACRO_DIR([cfg]) From 79e134ae8069c5b5a9a4e8c3446bb50c0b7fe413 Mon Sep 17 00:00:00 2001 From: rdkcmf Date: Thu, 25 Sep 2025 18:27:18 +0100 Subject: [PATCH 21/37] Deploy cla action --- .github/workflows/cla.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 0550479..c58b1b0 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -1,13 +1,20 @@ name: "CLA" + +permissions: + contents: read + pull-requests: write + actions: write + statuses: write + on: issue_comment: types: [created] pull_request_target: - types: [opened,closed,synchronize] + types: [opened, closed, synchronize] jobs: CLA-Lite: name: "Signature" - uses: rdkcentral/cmf-actions/.github/workflows/cla.yml@main + uses: rdkcentral/cmf-actions/.github/workflows/cla.yml@v1 secrets: - PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_ASSISTANT }} \ No newline at end of file + PERSONAL_ACCESS_TOKEN: ${{ secrets.CLA_ASSISTANT }} From 370c54f4b3d4108689e4b798a157ab4d729fd783 Mon Sep 17 00:00:00 2001 From: rdkcmf Date: Mon, 29 Sep 2025 14:11:50 +0100 Subject: [PATCH 22/37] Deploy fossid_integration_stateless_diffscan_target_repo action --- ...d_integration_stateless_diffscan_target_repo.yml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/fossid_integration_stateless_diffscan_target_repo.yml b/.github/workflows/fossid_integration_stateless_diffscan_target_repo.yml index da02b8b..7b8c1cb 100644 --- a/.github/workflows/fossid_integration_stateless_diffscan_target_repo.yml +++ b/.github/workflows/fossid_integration_stateless_diffscan_target_repo.yml @@ -1,11 +1,18 @@ name: Fossid Stateless Diff Scan -on: pull_request +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: read jobs: call-fossid-workflow: - uses: rdkcentral/build_tools_workflows/.github/workflows/fossid_integration_stateless_diffscan.yml@develop - secrets: + if: ${{ ! github.event.pull_request.head.repo.fork }} + uses: rdkcentral/build_tools_workflows/.github/workflows/fossid_integration_stateless_diffscan.yml@1.0.0 + secrets: FOSSID_CONTAINER_USERNAME: ${{ secrets.FOSSID_CONTAINER_USERNAME }} FOSSID_CONTAINER_PASSWORD: ${{ secrets.FOSSID_CONTAINER_PASSWORD }} FOSSID_HOST_USERNAME: ${{ secrets.FOSSID_HOST_USERNAME }} From 3e2cdb37b2e76df5cf3cf1e4e51bf03e3a0ff27f Mon Sep 17 00:00:00 2001 From: rosemarybennyy Date: Fri, 3 Oct 2025 19:33:32 +0530 Subject: [PATCH 23/37] RDKEMW-8798 : Post Code Coverage in the PR workflow (#27) Reason for change: Post Code Coverage in the PR workflow Test Procedure: Tested and verified Risks: Low Signed-off-by: Rose Mary Benny RoseMary_Benny@comcast.com --- .github/workflows/L1-tests.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index 3891817..5c39b58 100644 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -41,6 +41,7 @@ jobs: && sudo apt install -y tree automake libsqlite3-dev libcurl4-openssl-dev valgrind libgtest-dev lcov clang libsystemd-dev libboost-all-dev libwebsocketpp-dev meson libcunit1 libcunit1-dev + - name: Build gtest run: | cd /usr/src/gtest @@ -85,6 +86,12 @@ jobs: autoconf export ac_cv_func_malloc_0_nonnull=yes export ac_cv_func_memset=yes + # Enable coverage flags if applicable + if [ "${{matrix.coverage}}" = "with-coverage" ]; then + export CFLAGS="--coverage" + export CXXFLAGS="--coverage" + export LDFLAGS="--coverage" + fi ./configure "--prefix=${{github.workspace}}/install" make make install @@ -94,7 +101,25 @@ jobs: mkdir -p ${{env.RDKLOGGER_ROOT}}/unittests UNITTESTS="${{env.RDKLOGGER_ROOT}}/unittests" cd ${UNITTESTS} - cmake -B build -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install/usr -DDEP_LIB_PATH=${{env.LD_LIBRARY_PATH}} -DCMAKE_VERBOSE_MAKEFILE=ON + if [ "${{matrix.coverage}}" = "with-coverage" ]; then + cmake -B build -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install/usr -DDEP_LIB_PATH=${{env.LD_LIBRARY_PATH}} -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_CXX_FLAGS="--coverage" -DCMAKE_C_FLAGS="--coverage" + else + cmake -B build -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install/usr -DDEP_LIB_PATH=${{env.LD_LIBRARY_PATH}} -DCMAKE_VERBOSE_MAKEFILE=ON + fi make -C build cmake --install build ./build/rdk_logger_gtest + - name: Collect coverage report + if: ${{ matrix.coverage == 'with-coverage' }} + run: | + lcov --directory ${{env.RDKLOGGER_ROOT}}/src --capture --output-file coverage.info + lcov --remove coverage.info '/usr/*' "${{env.RDKLOGGER_PREFIX}}/*" --output-file coverage.info + - name: Generate the html report + run: | + genhtml coverage.info --output-directory /tmp/coverage_report + - name: Upload coverage report + if: ${{ matrix.coverage == 'with-coverage' }} + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: /tmp/coverage_report From a0e24181c3e7243c99e9a53b35aae69f24da5cdb Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Fri, 3 Oct 2025 20:19:42 +0530 Subject: [PATCH 24/37] RDKEMW-8528: Remove logMilestone.sh & use the binary when needed (#28) Reason for change: for optimization Test Procedure: Tested and verified Risks:Medium Priority:P1 --- scripts/logMilestone.sh | 57 ----------------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 scripts/logMilestone.sh diff --git a/scripts/logMilestone.sh b/scripts/logMilestone.sh deleted file mode 100644 index 122eb96..0000000 --- a/scripts/logMilestone.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh - -########################################################################## -# If not stated otherwise in this file or this component's LICENSE -# file the following copyright and licenses apply: -# -# Copyright 2016 RDK Management -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -########################################################################## - -. /etc/include.properties - -export PATH=$PATH:/usr/bin:/bin:/usr/local/bin:/sbin:/usr/local/sbin -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/lib/ - -if [ -z "$1" ]; -then - echo "Usage: `basename $0` " - exit 1 -fi - -if [ -f /lib/rdk/t2Shared_api.sh ]; then - source /lib/rdk/t2Shared_api.sh -fi - -#rdkLogMileStone will give uptime info in milliseconds. -UPTIME_BIN="/usr/bin/rdkLogMileStone" - -MILESTONE_EVENT=$1 - -if [ -f "$UPTIME_BIN" ]; then - #write uptime using rdkLogMileStone binary - uptime=`$UPTIME_BIN $1` - uptime_seconds=$(cut -d ' ' -f 1 /proc/uptime) - uptime_ms=$(awk -v up="$uptime_seconds" 'BEGIN { printf "%.0f", up * 1000 }') - - echo "Uptime_MS = $uptime_ms" - if [ "$1" == "CONNECT_TO_NTP_SERVER" ]; then - t2ValNotify "btime_ntpConnTime_split" "$uptime_ms" - elif [ "$1" == "RDK_STARTED" ]; then - t2ValNotify "btime_rdkstart_split" "$uptime_ms" - fi -else - echo "$UPTIME_BIN not found..!" - exit -1 -fi From 3d25a4e7436f09551abe9e7ed1586eec8b6966a8 Mon Sep 17 00:00:00 2001 From: Stephen Barrett Date: Wed, 8 Oct 2025 14:08:34 +0100 Subject: [PATCH 25/37] Update CODEOWNERS --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3c4a2f5..d8aad76 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,4 +2,4 @@ # the repo. Unless a later match takes precedence, # @global-owner1 and @global-owner2 will be requested for # review when someone opens a pull request. -* @rdkcentral/rdke_ghec_rdklogger_maintainer @rdkcentral/rdke_ghec_rdklogger_admin +* @rdkcentral/rdk_logger-maintainers From 3996cb2257c00cdf0b407d4307d04801cad46a9e Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Fri, 10 Oct 2025 06:50:11 +0530 Subject: [PATCH 26/37] RDKEMW-9247 : Moving rdklogger_milestone file from .cpp to .c (#30) * Rename rdk_logger_milestone.cpp to rdk_logger_milestone.c --- src/Makefile.am | 2 +- src/{rdk_logger_milestone.cpp => rdk_logger_milestone.c} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/{rdk_logger_milestone.cpp => rdk_logger_milestone.c} (98%) diff --git a/src/Makefile.am b/src/Makefile.am index feb50a3..683a31c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,7 @@ AM_CPPFLAGS = -pthread -Wall lib_LTLIBRARIES = librdkloggers.la -librdkloggers_la_SOURCES = rdk_debug.c rdk_debug_priv.c rdk_dynamic_logger.c rdk_logger_init.c rdk_logger_util.c rdk_logger_milestone.cpp +librdkloggers_la_SOURCES = rdk_debug.c rdk_debug_priv.c rdk_dynamic_logger.c rdk_logger_init.c rdk_logger_util.c rdk_logger_milestone.c librdkloggers_la_SOURCES += rdk_logger_onboard.c librdkloggers_la_CFLAGS = $(LOG4C_CFLAGS) $(GLIB_CFLAGS) $(SYSLOG_HELPER_CFLAGS) $(SYSTEMD_CLFAGS) -I./include -I../include -I${RDK_PROJECT_ROOT_PATH}/opensource/include/log4c -I${RDK_PROJECT_ROOT_PATH}/opensource/include -DDEBUG_CONF_FILE="\"debug.ini\"" librdkloggers_la_LDFLAGS = $(GLIB_LIBS) $(LOG4C_LIBS) $(SYSLOG_HELPER_LDFLAGS) $(SYSTEMD_LDFLAGS) diff --git a/src/rdk_logger_milestone.cpp b/src/rdk_logger_milestone.c similarity index 98% rename from src/rdk_logger_milestone.cpp rename to src/rdk_logger_milestone.c index 36b4a7d..8ca4d8a 100644 --- a/src/rdk_logger_milestone.cpp +++ b/src/rdk_logger_milestone.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include "rdk_logger_milestone.h" From c9ea7f372bc890ec7a8153010e229038aff4d3af Mon Sep 17 00:00:00 2001 From: rosemarybennyy Date: Thu, 30 Oct 2025 04:21:17 +0530 Subject: [PATCH 27/37] RDKEMW-6710: RDKLogger - Improve L1 Test coverage (#31) * RDKEMW-6710 : RDKLogger - Improve L1 Test coverage Reason for change: RDKLogger - Improve L1 Test coverage Test Procedure: Tested and verified Risks: Low Signed-off-by: RoseMary_Benny@comcast.com --- .github/workflows/L1-tests.yml | 10 +- src/rdk_debug_priv.c | 1 - unittests/CMakeLists.txt | 13 + unittests/Gtest_log4crc | 139 +------- unittests/rdkEnableLogLevel.cpp | 135 ++++++++ unittests/rdkLogLevelFromString.cpp | 130 +++++++ unittests/rdkLoggerConfigTest.cpp | 237 +++++++++++++ unittests/rdkLoggerDynamic.cpp | 331 ++++++++++++++++++ unittests/rdkLoggerErrorTest.cpp | 366 ++++++++++++++++++++ unittests/rdkLoggerPerformanceTest.cpp | 449 +++++++++++++++++++++++++ unittests/rdkLoggerRotationTest.cpp | 422 +++++++++++++++++++++++ unittests/rdkLoggerStreamEnvTest.cpp | 105 ++++++ unittests/rdkLoggerUtilityTest.cpp | 60 ++++ unittests/rdkloggerInit.cpp | 10 +- unittests/rdkloggerMsgPrintf.cpp | 2 + unittests/rdkloggerMsgRaw.cpp | 298 ++++++++++++++++ unittests/rdkloggerMsgRaw1.cpp | 323 ++++++++++++++++++ unittests/sample_gtest_debug.ini | 22 +- 18 files changed, 2895 insertions(+), 158 deletions(-) create mode 100644 unittests/rdkEnableLogLevel.cpp create mode 100644 unittests/rdkLogLevelFromString.cpp create mode 100644 unittests/rdkLoggerConfigTest.cpp create mode 100644 unittests/rdkLoggerDynamic.cpp create mode 100644 unittests/rdkLoggerErrorTest.cpp create mode 100644 unittests/rdkLoggerPerformanceTest.cpp create mode 100644 unittests/rdkLoggerRotationTest.cpp create mode 100644 unittests/rdkLoggerStreamEnvTest.cpp create mode 100644 unittests/rdkLoggerUtilityTest.cpp create mode 100644 unittests/rdkloggerMsgRaw.cpp create mode 100644 unittests/rdkloggerMsgRaw1.cpp diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index 5c39b58..5379edf 100644 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -88,8 +88,8 @@ jobs: export ac_cv_func_memset=yes # Enable coverage flags if applicable if [ "${{matrix.coverage}}" = "with-coverage" ]; then - export CFLAGS="--coverage" - export CXXFLAGS="--coverage" + export CFLAGS="-DLOGMILESTONE=ON -DONBOARDING_FILE=ON --coverage" + export CXXFLAGS="-DLOGMILESTONE=ON -DONBOARDING_FILE=ON --coverage" export LDFLAGS="--coverage" fi ./configure "--prefix=${{github.workspace}}/install" @@ -98,11 +98,15 @@ jobs: - name: Build and execute L1 unittesting for rdk_logger run: | + mkdir -p /opt/logs + sudo touch /opt/logs/rdk_milestones.log + sudo chmod 666 /opt/logs/rdk_milestones.log mkdir -p ${{env.RDKLOGGER_ROOT}}/unittests UNITTESTS="${{env.RDKLOGGER_ROOT}}/unittests" + cp ${{github.workspace}}/install/bin/rdklogctrl ${UNITTESTS}/ cd ${UNITTESTS} if [ "${{matrix.coverage}}" = "with-coverage" ]; then - cmake -B build -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install/usr -DDEP_LIB_PATH=${{env.LD_LIBRARY_PATH}} -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_CXX_FLAGS="--coverage" -DCMAKE_C_FLAGS="--coverage" + cmake -B build -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install/usr -DDEP_LIB_PATH=${{env.LD_LIBRARY_PATH}} -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_CXX_FLAGS="--coverage" -DCMAKE_C_FLAGS="--coverage -DLOGMILESTONE=ON" else cmake -B build -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/install/usr -DDEP_LIB_PATH=${{env.LD_LIBRARY_PATH}} -DCMAKE_VERBOSE_MAKEFILE=ON fi diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index e805e93..59f0ca2 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -366,7 +366,6 @@ void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const cha /* Handling process request here. This is not a blocking call and it shall return immediately */ rdk_dyn_log_process_pending_request(); - cat = log4c_category_get(module_name); prio = log4c_category_get_priority(cat); if (cat && prio == LOG4C_PRIORITY_NOTSET && gRootCat) { diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 37b9675..77b246a 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -25,15 +25,28 @@ find_package(GTest REQUIRED) enable_testing() link_directories("${DEP_LIB_PATH}/") + # Add the test executable add_executable( rdk_logger_gtest rdkloggerInit.cpp rdkloggerMsgPrintf.cpp rdkloggerMsgVsprintf.cpp + rdkloggerMsgRaw.cpp + rdkloggerMsgRaw1.cpp rdkIsDbgEnabled.cpp + rdkLoggerDynamic.cpp + rdkLoggerUtilityTest.cpp + rdkLoggerConfigTest.cpp + rdkEnableLogLevel.cpp + rdkLogLevelFromString.cpp + rdkLoggerRotationTest.cpp + rdkLoggerErrorTest.cpp + rdkLoggerPerformanceTest.cpp + rdkLoggerStreamEnvTest.cpp main.cpp ) +add_compile_definitions(LOGMILESTONE=ON) target_compile_definitions(rdk_logger_gtest PRIVATE GTEST_DEBUG_INI_FILE="sample_gtest_debug.ini") diff --git a/unittests/Gtest_log4crc b/unittests/Gtest_log4crc index 806a5fd..ae4ffea 100644 --- a/unittests/Gtest_log4crc +++ b/unittests/Gtest_log4crc @@ -17,154 +17,17 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - 0 0 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/unittests/rdkEnableLogLevel.cpp b/unittests/rdkEnableLogLevel.cpp new file mode 100644 index 0000000..29daa98 --- /dev/null +++ b/unittests/rdkEnableLogLevel.cpp @@ -0,0 +1,135 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file + * the following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +/****************************************************** +Test Case : Testing rdk_logger function rdk_logger_msg_printf +*******************************************************/ + +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" +#if 1 +TEST(rdkEnableLogLevel, NULL_log_enabled) +{ + + rdk_logger_Bool ret = TRUE; + rdk_Error rdk_err = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + + rdk_err = rdk_logger_init(conf_file); + ASSERT_EQ(rdk_err,RDK_SUCCESS)<<"rdk_logger_init failed with err:\""<name()); + ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYFATAL", RDK_LOG_FATAL); + rdk_logger_msg_printf(RDK_LOG_FATAL, "LOG.RDK.ONLYFATAL", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); +} +TEST(rdkEnableLogLevel, ONLYWARNING_log_enabled) +{ + rdk_logger_Bool ret = TRUE; + rdk_Error rdk_err = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + rdk_err = rdk_logger_init(conf_file); + ASSERT_EQ(rdk_err,RDK_SUCCESS)<<"rdk_logger_init failed with err:\""<name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); +// ret = rdk_logger_deinit(); +// ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< +#include +#include "rdk_logger.h" +#include "gtest_app.h" + +TEST(rdkLogLevelFromString, test_log_level_from_string) +{ + rdk_LogLevel level = RDK_LOG_NONE; + rdk_Error rdk_err = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + + rdk_err = rdk_logger_init(conf_file); + ASSERT_EQ(rdk_err,RDK_SUCCESS)<<"rdk_logger_init failed with err:\""< +#include +#include +#include +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" + +class RDKLoggerConfigTest : public ::testing::Test { +protected: + void SetUp() override { + // Create temporary directory for test files + system("mkdir -p /tmp/rdk_logger_test"); + + // Create test configuration files + createTestConfigFile("/tmp/rdk_logger_test/valid.ini", + "LOG.RDK.DEFAULT=INFO\n" + "LOG.RDK.TEST=DEBUG\n" + "LOG.RDK.ERROR=ERROR\n"); + + createTestConfigFile("/tmp/rdk_logger_test/empty.ini", ""); + + createTestConfigFile("/tmp/rdk_logger_test/malformed.ini", + "LOG.RDK.DEFAULT=INFO\n" + "INVALID_LINE_WITHOUT_EQUALS\n" + "LOG.RDK.TEST=DEBUG\n"); + + createTestConfigFile("/tmp/rdk_logger_test/comments.ini", + "# This is a comment\n" + "LOG.RDK.DEFAULT=WARNING\n" + "# Another comment\n" + "LOG.RDK.TEST=DEBUG\n"); + + createTestConfigFile("/tmp/rdk_logger_test/whitespace.ini", + "LOG.RDK.DEFAULT = INFO \n" + " LOG.RDK.TEST = DEBUG \n" + "LOG.RDK.ERROR=ERROR\n"); + } + + void TearDown() override { + // Cleanup test files + system("rm -rf /tmp/rdk_logger_test"); + + // Reset logger state + rdk_logger_deinit(); + } + + void createTestConfigFile(const char* filename, const char* content) { + FILE* file = fopen(filename, "w"); + if (file) { + fprintf(file, "%s", content); + fclose(file); + } + } +}; + +// Test valid configuration file parsing +TEST_F(RDKLoggerConfigTest, ValidConfigFileParsing) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/valid.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize with valid config file"; + + // Test that configuration was parsed correctly + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "DEBUG level should be enabled for LOG.RDK.TEST"; + + enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.ERROR", RDK_LOG_ERROR); + EXPECT_EQ(enabled, TRUE) << "ERROR level should be enabled for LOG.RDK.ERROR"; +} + +// Test empty configuration file +TEST_F(RDKLoggerConfigTest, EmptyConfigFile) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/empty.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle empty config file gracefully"; +} + +// Test malformed configuration file +TEST_F(RDKLoggerConfigTest, MalformedConfigFile) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/malformed.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle malformed config file gracefully"; + + // Should still parse valid lines + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Valid lines should still be parsed"; +} + +// Test configuration file with comments +TEST_F(RDKLoggerConfigTest, ConfigFileWithComments) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/comments.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle config file with comments"; + + // Comments should be ignored + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Comments should be ignored"; +} + +// Test configuration file with whitespace +TEST_F(RDKLoggerConfigTest, ConfigFileWithWhitespace) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/whitespace.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle config file with whitespace"; + + // Whitespace should be trimmed + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Whitespace should be trimmed"; +} +// Test NULL configuration file path +TEST_F(RDKLoggerConfigTest, NullConfigFile) { + rdk_Error ret = rdk_logger_init(NULL); + // Should use default configuration file + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle NULL config file path"; +} + +// Test very large configuration file +TEST_F(RDKLoggerConfigTest, LargeConfigFile) { + // Create a large configuration file + FILE* file = fopen("/tmp/rdk_logger_test/large.ini", "w"); + ASSERT_TRUE(file != NULL) << "Failed to create large config file"; + + // Write many configuration entries + for (int i = 0; i < 1000; i++) { + fprintf(file, "LOG.RDK.MODULE%d=DEBUG\n", i); + } + fclose(file); + + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/large.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle large config file"; + + // Test a few entries + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.MODULE0", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Should parse large config file correctly"; + + enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.MODULE999", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Should parse large config file correctly"; +} + +// Test configuration file with duplicate entries +TEST_F(RDKLoggerConfigTest, DuplicateConfigEntries) { + createTestConfigFile("/tmp/rdk_logger_test/duplicate.ini", + "LOG.RDK.TEST=DEBUG\n" + "LOG.RDK.TEST=ERROR\n" // Duplicate entry + "LOG.RDK.TEST=INFO\n"); // Another duplicate + + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/duplicate.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle duplicate config entries"; + + // Last entry should take precedence + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", RDK_LOG_INFO); + EXPECT_EQ(enabled, TRUE) << "Last duplicate entry should take precedence"; +} + +// Test configuration file with invalid log levels +TEST_F(RDKLoggerConfigTest, InvalidLogLevels) { + createTestConfigFile("/tmp/rdk_logger_test/invalid_levels.ini", + "LOG.RDK.DEFAULT=INVALID_LEVEL\n" + "LOG.RDK.TEST=DEBUG\n" + "LOG.RDK.ERROR=UNKNOWN_LEVEL\n"); + + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/invalid_levels.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle invalid log levels gracefully"; + + // Valid entries should still work + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Valid log levels should still work"; +} + +// Test configuration file with very long module names +TEST_F(RDKLoggerConfigTest, LongModuleNames) { + char long_module[256]; + snprintf(long_module, sizeof(long_module), "LOG.RDK.%s", + "VERY_LONG_MODULE_NAME_THAT_EXCEEDS_NORMAL_LENGTH_AND_SHOULD_BE_HANDLED_GRACEFULLY_BY_THE_CONFIGURATION_PARSER"); + + FILE* file = fopen("/tmp/rdk_logger_test/long_names.ini", "w"); + ASSERT_TRUE(file != NULL) << "Failed to create config file with long names"; + fprintf(file, "LOG.RDK.DEFAULT=INFO\n"); + fprintf(file, "%s=DEBUG\n", long_module); + fclose(file); + + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/long_names.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle long module names"; + + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled(long_module, RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Long module names should be handled correctly"; +} + +// Test configuration file with special characters +TEST_F(RDKLoggerConfigTest, SpecialCharactersInConfig) { + createTestConfigFile("/tmp/rdk_logger_test/special_chars.ini", + "LOG.RDK.DEFAULT=INFO\n" + "LOG.RDK.TEST_WITH_UNDERSCORES=DEBUG\n" + "LOG.RDK.TEST-WITH-DASHES=ERROR\n" + "LOG.RDK.TEST.WITH.DOTS=WARNING\n"); + + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/special_chars.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle special characters in module names"; + + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST_WITH_UNDERSCORES", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Underscores should be handled correctly"; +} + +// Test configuration file with mixed case log levels +TEST_F(RDKLoggerConfigTest, MixedCaseLogLevels) { + createTestConfigFile("/tmp/rdk_logger_test/mixed_case.ini", + "LOG.RDK.DEFAULT=info\n" + "LOG.RDK.TEST=debug\n" + "LOG.RDK.ERROR=ERROR\n" + "LOG.RDK.WARNING=Warning\n"); + + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_test/mixed_case.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle mixed case log levels"; + + rdk_logger_Bool enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", RDK_LOG_DEBUG); + EXPECT_EQ(enabled, TRUE) << "Lowercase log levels should be handled correctly"; + + enabled = rdk_logger_is_logLevel_enabled("LOG.RDK.WARNING", RDK_LOG_WARN); + EXPECT_EQ(enabled, TRUE) << "Mixed case log levels should be handled correctly"; +} diff --git a/unittests/rdkLoggerDynamic.cpp b/unittests/rdkLoggerDynamic.cpp new file mode 100644 index 0000000..3895fa4 --- /dev/null +++ b/unittests/rdkLoggerDynamic.cpp @@ -0,0 +1,331 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file + * the following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#include +#include +#include +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" +typedef enum { + CAT_FATAL, + CAT_ERROR, + CAT_WARN, + CAT_NOTICE, + CAT_INFO, + CAT_DEBUG, + CAT_TRACE, + CAT_NONE +} LogCategory; + +typedef enum { + LVL_FATAL, + LVL_ERROR, + LVL_WARN, + LVL_NOTICE, + LVL_INFO, + LVL_DEBUG, + LVL_TRACE, + LVL_NONE, + LVL_TEST +} LogLevel; + +typedef struct { + LogCategory category; + LogLevel level; +} rdklogctrl_args_t; + +void* run_rdklogctrl(void* arg) { + rdklogctrl_args_t* args = (rdklogctrl_args_t*)arg; + char category_str[32] = ""; + char level_str[16] = ""; + + // Switch-case for category + switch (args->category) { + case CAT_FATAL: + strcpy(category_str, "LOG.RDK.FATAL"); + break; + case CAT_ERROR: + strcpy(category_str, "LOG.RDK.ERROR"); + break; + case CAT_WARN: + strcpy(category_str, "LOG.RDK.WARN"); + break; + case CAT_NOTICE: + strcpy(category_str, "LOG.RDK.NOTICE"); + break; + case CAT_INFO: + strcpy(category_str, "LOG.RDK.INFO"); + break; + case CAT_DEBUG: + strcpy(category_str, "LOG.RDK.DEBUG"); + break; + case CAT_TRACE: + strcpy(category_str, "LOG.RDK.TRACE"); + break; + case CAT_NONE: + strcpy(category_str, "LOG.RDK.NONE"); + break; + default: + break; + } + + // Switch-case for level + switch (args->level) { + case LVL_FATAL: + strcpy(level_str, "FATAL"); + break; + case LVL_ERROR: + strcpy(level_str, "ERROR"); + break; + case LVL_WARN: + strcpy(level_str, "WARN"); + break; + case LVL_NOTICE: + strcpy(level_str, "NOTICE"); + break; + case LVL_INFO: + strcpy(level_str, "INFO"); + break; + case LVL_DEBUG: + strcpy(level_str, "DEBUG"); + break; + case LVL_TRACE: + strcpy(level_str, "TRACE"); + break; + case LVL_NONE: + strcpy(level_str, "NONE"); + break; + case LVL_TEST: + strcpy(level_str, "~NONE"); + break; + default: + break; + } + + char cmd[256]; + snprintf(cmd, sizeof(cmd), "./rdklogctrl rdk_logger_gtest %s %s", category_str, level_str); + fprintf(stderr, "Executing command: %s\n", cmd); + int ret = system(cmd); + (void)ret; + return NULL; +} + +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_fatal) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_FATAL; + args.level = LVL_FATAL; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); +} + +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_error) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_ERROR; + args.level = LVL_ERROR; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); +} +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_warn) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_WARN; + args.level = LVL_WARN; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); +} +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_notice) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_NOTICE; + args.level = LVL_NOTICE; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); +} +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_info) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_INFO; + args.level = LVL_INFO; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); +} +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_debug) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_DEBUG; + args.level = LVL_DEBUG; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); +} +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_trace) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_TRACE; + args.level = LVL_TRACE; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); +} +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_none) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_NONE; + args.level = LVL_NONE; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); +} + +TEST(RdkDynamicLoggerTest, MessageProcessingViaSystem_negnone) { + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + EXPECT_EQ(rdk_logger_init(conf_file), 0); + + // Prepare arguments for thread + rdklogctrl_args_t args; + args.category = CAT_NONE; + args.level = LVL_TEST; + + // Spawn a thread to run rdklogctrl (client) + pthread_t client_thread; + ASSERT_EQ(0, pthread_create(&client_thread, nullptr, run_rdklogctrl, &args)); + + // Wait briefly to allow message to be sent + usleep(500000); // 0.5 seconds + + // Log a message using the high-level API, which will exercise dynamic logger code + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.TESTMOD", "Test message for dynamic logger\n"); + // Clean up + pthread_join(client_thread, nullptr); + +} + diff --git a/unittests/rdkLoggerErrorTest.cpp b/unittests/rdkLoggerErrorTest.cpp new file mode 100644 index 0000000..db1f879 --- /dev/null +++ b/unittests/rdkLoggerErrorTest.cpp @@ -0,0 +1,366 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file + * the following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +/****************************************************** +Test Case : Testing RDK Logger Error Handling and Edge Cases +*******************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" + +class RDKLoggerErrorTest : public ::testing::Test { +protected: + void SetUp() override { + // Create test configuration file + system("mkdir -p /tmp/rdk_logger_error_test"); + createTestConfigFile("/tmp/rdk_logger_error_test/test.ini", + "LOG.RDK.DEFAULT=INFO\n" + "LOG.RDK.TEST=DEBUG\n"); + } + + void TearDown() override { + // Cleanup + system("rm -rf /tmp/rdk_logger_error_test"); + rdk_logger_deinit(); + } + + void createTestConfigFile(const char* filename, const char* content) { + FILE* file = fopen(filename, "w"); + if (file) { + fprintf(file, "%s", content); + fclose(file); + } + } +}; + +// Test NULL pointer handling in logging functions +TEST_F(RDKLoggerErrorTest, NullPointerHandling) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test NULL module name + rdk_logger_msg_printf(RDK_LOG_INFO, NULL, "Test message"); + // Should not crash, but may not log anything + + // Test NULL format string + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", NULL); + // Should not crash + + // Test NULL module name in enable_logLevel + rdk_logger_Bool result = rdk_logger_enable_logLevel(NULL, RDK_LOG_INFO, TRUE); + EXPECT_EQ(result, FALSE) << "Should return FALSE for NULL module name"; + + // Test NULL module name in is_logLevel_enabled + result = rdk_logger_is_logLevel_enabled(NULL, RDK_LOG_INFO); + EXPECT_EQ(result, FALSE) << "Should return FALSE for NULL module name"; +} + +// Test empty string handling +TEST_F(RDKLoggerErrorTest, EmptyStringHandling) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test empty module name + rdk_logger_msg_printf(RDK_LOG_INFO, " ", "Test message"); + // Should not crash + + // Test empty format string + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", " "); + // Should not crash + + // Test empty module name in enable_logLevel + rdk_logger_Bool result = rdk_logger_enable_logLevel("", RDK_LOG_INFO, TRUE); + // Should handle gracefully + + // Test empty module name in is_logLevel_enabled + result = rdk_logger_is_logLevel_enabled("", RDK_LOG_INFO); + // Should handle gracefully +} + +// Test invalid log levels +TEST_F(RDKLoggerErrorTest, InvalidLogLevels) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test invalid log level (beyond enum range) + rdk_logger_msg_printf((rdk_LogLevel)999, "LOG.RDK.TEST", "Test message"); + // Should not crash, may use default level + + // Test invalid log level in enable_logLevel + rdk_logger_Bool result = rdk_logger_enable_logLevel("LOG.RDK.TEST", (rdk_LogLevel)999, TRUE); + // Should handle gracefully + + // Test invalid log level in is_logLevel_enabled + result = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", (rdk_LogLevel)999); + // Should handle gracefully +} + +// Test very long messages +TEST_F(RDKLoggerErrorTest, VeryLongMessages) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Create a very long message + char long_message[10000]; + memset(long_message, 'A', sizeof(long_message) - 1); + long_message[sizeof(long_message) - 1] = '\0'; + + // Test very long message + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Long message: %s", long_message); + // Should not crash, may truncate or handle gracefully + + // Test very long format string + char long_format[5000]; + memset(long_format, '%', sizeof(long_format) - 1); + long_format[sizeof(long_format) - 1] = '\0'; + + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", long_format, "test"); + // Should not crash +} + +// Test very long module names +TEST_F(RDKLoggerErrorTest, VeryLongModuleNames) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Create a very long module name + char long_module[1000]; + memset(long_module, 'A', sizeof(long_module) - 1); + long_module[sizeof(long_module) - 1] = '\0'; + + // Test very long module name + rdk_logger_msg_printf(RDK_LOG_INFO, long_module, "Test message"); + // Should not crash + + // Test very long module name in enable_logLevel + rdk_logger_Bool result = rdk_logger_enable_logLevel(long_module, RDK_LOG_INFO, TRUE); + // Should handle gracefully + + // Test very long module name in is_logLevel_enabled + result = rdk_logger_is_logLevel_enabled(long_module, RDK_LOG_INFO); + // Should handle gracefully +} + +// Test special characters in messages +TEST_F(RDKLoggerErrorTest, SpecialCharactersInMessages) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test various special characters + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Special chars: \n\r\t\b\f\v\\\"'"); + // Should handle special characters correctly + + // Test Unicode characters (if supported) + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Unicode: \u00A9 \u00AE \u2122"); + // Should handle Unicode characters + + // Test control characters + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Control: %c%c%c", 0x01, 0x02, 0x03); + // Should handle control characters +} + +// Test format string vulnerabilities +TEST_F(RDKLoggerErrorTest, FormatStringVulnerabilities) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test format string with %n (should be handled safely) + int n_value = 0; + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Test %n message", &n_value); + // Should not crash or cause security issues + + // Test format string with %s and NULL + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Test %s message", (char*)"(null)"); + // Should handle NULL string parameter safely + + // Test format string with %d and invalid pointer + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Test %d message", 0); + // Should handle invalid pointer safely +} + +// Test multiple initialization calls +TEST_F(RDKLoggerErrorTest, MultipleInitialization) { + // First initialization + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "First initialization should succeed"; + + // Second initialization (should be handled gracefully) + ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Second initialization should be handled gracefully"; + + // Test that logging still works + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Test message after multiple init"); + // Should work correctly +} + +// Test deinitialization without initialization +TEST_F(RDKLoggerErrorTest, DeinitWithoutInit) { + // Deinitialize without initializing first + rdk_Error ret = rdk_logger_deinit(); + ASSERT_EQ(ret, RDK_SUCCESS) << "Deinit without init should be handled gracefully"; + + // Try to log after deinit without init + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Test message after deinit"); + // Should not crash +} + +// Test logging after deinitialization +TEST_F(RDKLoggerErrorTest, LoggingAfterDeinit) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Deinitialize + ret = rdk_logger_deinit(); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to deinitialize logger"; + + // Try to log after deinit + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Test message after deinit"); + // Should not crash, may not log anything +} + +// Test enable_logLevel with invalid parameters +TEST_F(RDKLoggerErrorTest, EnableLogLevelInvalidParams) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test with NULL module name + rdk_logger_Bool result = rdk_logger_enable_logLevel(NULL, RDK_LOG_INFO, TRUE); + EXPECT_EQ(result, FALSE) << "Should return FALSE for NULL module name"; + + // Test with empty module name + result = rdk_logger_enable_logLevel("", RDK_LOG_INFO, TRUE); + // Should handle gracefully + + // Test with invalid log level + result = rdk_logger_enable_logLevel("LOG.RDK.TEST", (rdk_LogLevel)999, TRUE); + // Should handle gracefully +} + +// Test is_logLevel_enabled with invalid parameters +TEST_F(RDKLoggerErrorTest, IsLogLevelEnabledInvalidParams) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test with NULL module name + rdk_logger_Bool result = rdk_logger_is_logLevel_enabled(NULL, RDK_LOG_INFO); + EXPECT_EQ(result, FALSE) << "Should return FALSE for NULL module name"; + + // Test with empty module name + result = rdk_logger_is_logLevel_enabled("", RDK_LOG_INFO); + // Should handle gracefully + + // Test with invalid log level + result = rdk_logger_is_logLevel_enabled("LOG.RDK.TEST", (rdk_LogLevel)999); + // Should handle gracefully +} + +// Test rdk_logger_level_from_string with invalid inputs +TEST_F(RDKLoggerErrorTest, LevelFromStringInvalidInputs) { + // Test NULL input + rdk_LogLevel level = rdk_logger_level_from_string(NULL); + EXPECT_EQ(level, RDK_LOG_NONE) << "Should return RDK_LOG_NONE for NULL input"; + + // Test empty string + level = rdk_logger_level_from_string(""); + EXPECT_EQ(level, RDK_LOG_NONE) << "Should return RDK_LOG_NONE for empty string"; + + // Test invalid string + level = rdk_logger_level_from_string("INVALID_LEVEL"); + EXPECT_EQ(level, RDK_LOG_NONE) << "Should return RDK_LOG_NONE for invalid string"; + + // Test partial string + level = rdk_logger_level_from_string("DEBU"); + EXPECT_EQ(level, RDK_LOG_NONE) << "Should return RDK_LOG_NONE for partial string"; + + // Test mixed case (should work) + level = rdk_logger_level_from_string("debug"); + EXPECT_EQ(level, RDK_LOG_DEBUG) << "Should handle lowercase correctly"; + + level = rdk_logger_level_from_string("Debug"); + EXPECT_EQ(level, RDK_LOG_DEBUG) << "Should handle mixed case correctly"; +} + +// Test rdk_logger_log_onboard with invalid parameters +TEST_F(RDKLoggerErrorTest, LogOnboardInvalidParams) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test with NULL module name + rdk_logger_log_onboard(NULL, "Test message"); + // Should not crash + + // Test with NULL message + rdk_logger_log_onboard("LOG.RDK.TEST", NULL); + // Should not crash + + // Test with empty module name + rdk_logger_log_onboard(" ", "Test message"); + // Should not crash + + // Test with empty message + rdk_logger_log_onboard("LOG.RDK.TEST", " "); + // Should not crash +} + +// Test legacy functions with invalid parameters +TEST_F(RDKLoggerErrorTest, LegacyFunctionsInvalidParams) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test rdk_dbg_MsgRaw with NULL parameters + rdk_dbg_MsgRaw(RDK_LOG_INFO, NULL, "Test message"); + // Should not crash + + rdk_dbg_MsgRaw(RDK_LOG_INFO, "LOG.RDK.TEST", NULL); + // Should not crash + + // Test rdk_dbg_MsgRaw1 with NULL parameters + // Note: rdk_dbg_MsgRaw1 requires va_list, so we test it differently + // We'll test the function by calling it with a simple va_list setup + rdk_dbg_MsgRaw(RDK_LOG_INFO, NULL, "Test message"); + // Should not crash + + rdk_dbg_MsgRaw(RDK_LOG_INFO, "LOG.RDK.TEST", NULL); + // Should not crash +} + +// Test memory allocation edge cases +TEST_F(RDKLoggerErrorTest, MemoryAllocationEdgeCases) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_error_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test with very large number of modules + for (int i = 0; i < 10000; i++) { + char module_name[100]; + snprintf(module_name, sizeof(module_name), "LOG.RDK.MODULE%d", i); + rdk_logger_msg_printf(RDK_LOG_INFO, module_name, "Test message %d", i); + } + // Should handle large number of modules gracefully + + // Test rapid logging + for (int i = 0; i < 1000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.TEST", "Rapid message %d", i); + } + // Should handle rapid logging gracefully +} diff --git a/unittests/rdkLoggerPerformanceTest.cpp b/unittests/rdkLoggerPerformanceTest.cpp new file mode 100644 index 0000000..53f6823 --- /dev/null +++ b/unittests/rdkLoggerPerformanceTest.cpp @@ -0,0 +1,449 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file + * the following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +/****************************************************** +Test Case : Testing RDK Logger Performance and Stress Testing +*******************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" + +class RDKLoggerPerformanceTest : public ::testing::Test { +protected: + void SetUp() override { + // Create test directory + system("mkdir -p /tmp/rdk_logger_performance_test"); + + // Create test configuration file + createTestConfigFile("/tmp/rdk_logger_performance_test/test.ini", + "LOG.RDK.DEFAULT=INFO\n" + "LOG.RDK.PERFORMANCE=DEBUG\n" + "LOG.RDK.STRESS=TRACE\n"); + } + + void TearDown() override { + // Cleanup + system("rm -rf /tmp/rdk_logger_performance_test"); + rdk_logger_deinit(); + } + + void createTestConfigFile(const char* filename, const char* content) { + FILE* file = fopen(filename, "w"); + if (file) { + fprintf(file, "%s", content); + fclose(file); + } + } + + double getTimeDifference(struct timeval* start, struct timeval* end) { + return (end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec) / 1000000.0; + } + + void* threadFunction(void* arg) { + int thread_id = *(int*)arg; + for (int i = 0; i < 1000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "Thread %d message %d", thread_id, i); + } + return NULL; + } +}; + +// Test basic logging performance +TEST_F(RDKLoggerPerformanceTest, BasicLoggingPerformance) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log 10000 messages + for (int i = 0; i < 10000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "Performance test message %d", i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 10000 messages in %.3f seconds (%.0f messages/sec)\n", + elapsed, 10000.0 / elapsed); + + // Should complete in reasonable time (less than 10 seconds) + EXPECT_LT(elapsed, 10.0) << "Logging should be reasonably fast"; +} + +// Test logging with different log levels +TEST_F(RDKLoggerPerformanceTest, DifferentLogLevelsPerformance) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages with different levels + for (int i = 0; i < 1000; i++) { + rdk_logger_msg_printf(RDK_LOG_FATAL, "LOG.RDK.PERFORMANCE", "Fatal message %d", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.PERFORMANCE", "Error message %d", i); + rdk_logger_msg_printf(RDK_LOG_WARN, "LOG.RDK.PERFORMANCE", "Warning message %d", i); + rdk_logger_msg_printf(RDK_LOG_NOTICE, "LOG.RDK.PERFORMANCE", "Notice message %d", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", "Info message %d", i); + rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.PERFORMANCE", "Debug message %d", i); + rdk_logger_msg_printf(RDK_LOG_TRACE, "LOG.RDK.PERFORMANCE", "Trace message %d", i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 7000 messages with different levels in %.3f seconds (%.0f messages/sec)\n", + elapsed, 7000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 10.0) << "Logging with different levels should be reasonably fast"; +} + +// Test logging with different module names +TEST_F(RDKLoggerPerformanceTest, DifferentModuleNamesPerformance) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages with different module names + for (int i = 0; i < 1000; i++) { + char module_name[50]; + snprintf(module_name, sizeof(module_name), "LOG.RDK.MODULE%d", i % 100); + rdk_logger_msg_printf(RDK_LOG_INFO, module_name, "Message %d", i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 1000 messages with different modules in %.3f seconds (%.0f messages/sec)\n", + elapsed, 1000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 5.0) << "Logging with different modules should be reasonably fast"; +} + +// Test logging with long messages +TEST_F(RDKLoggerPerformanceTest, LongMessagesPerformance) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Create a long message + char long_message[1000]; + memset(long_message, 'A', sizeof(long_message) - 1); + long_message[sizeof(long_message) - 1] = '\0'; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages with long content + for (int i = 0; i < 1000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "Long message %d: %s", i, long_message); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 1000 long messages in %.3f seconds (%.0f messages/sec)\n", + elapsed, 1000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 10.0) << "Logging long messages should be reasonably fast"; +} + +// Test logging with complex format strings +TEST_F(RDKLoggerPerformanceTest, ComplexFormatStringsPerformance) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages with complex format strings + for (int i = 0; i < 1000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "Complex format: %d %s %f %c %x %o %p", + i, "test", 3.14, 'A', i, i, &i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 1000 complex format messages in %.3f seconds (%.0f messages/sec)\n", + elapsed, 1000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 10.0) << "Logging complex format strings should be reasonably fast"; +} + +// Test logging with rapid calls +TEST_F(RDKLoggerPerformanceTest, RapidCallsPerformance) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages rapidly + for (int i = 0; i < 5000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", "Rapid message %d", i); + rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.PERFORMANCE", "Rapid debug %d", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.PERFORMANCE", "Rapid error %d", i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 15000 rapid messages in %.3f seconds (%.0f messages/sec)\n", + elapsed, 15000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 15.0) << "Rapid logging should be reasonably fast"; +} + +// Test logging with memory usage +TEST_F(RDKLoggerPerformanceTest, MemoryUsageTest) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct rusage usage_before, usage_after; + getrusage(RUSAGE_SELF, &usage_before); + + // Log many messages + for (int i = 0; i < 10000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "Memory test message %d", i); + } + + getrusage(RUSAGE_SELF, &usage_after); + + long memory_diff = usage_after.ru_maxrss - usage_before.ru_maxrss; + printf("Memory usage increased by %ld KB\n", memory_diff); + + // Memory usage should be reasonable (less than 10MB) + EXPECT_LT(memory_diff, 10240) << "Memory usage should be reasonable"; +} + +// Test logging with CPU usage +TEST_F(RDKLoggerPerformanceTest, CPUUsageTest) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct rusage usage_before, usage_after; + getrusage(RUSAGE_SELF, &usage_before); + + // Log many messages + for (int i = 0; i < 10000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "CPU test message %d", i); + } + + getrusage(RUSAGE_SELF, &usage_after); + + long cpu_diff = usage_after.ru_utime.tv_sec - usage_before.ru_utime.tv_sec; + printf("CPU usage increased by %ld seconds\n", cpu_diff); + + // CPU usage should be reasonable (less than 5 seconds) + EXPECT_LT(cpu_diff, 5) << "CPU usage should be reasonable"; +} + +// Test logging with file I/O stress +TEST_F(RDKLoggerPerformanceTest, FileIOStressTest) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "stress_test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_performance_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; // 1KB max size to trigger rotation + config.maxCount = 5; // Keep 5 files + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log many messages to trigger file rotation + for (int i = 0; i < 5000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "File I/O stress test message %d", i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 5000 messages with file rotation in %.3f seconds (%.0f messages/sec)\n", + elapsed, 5000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 20.0) << "File I/O stress test should be reasonably fast"; +} + +// Test logging with signal handling +TEST_F(RDKLoggerPerformanceTest, SignalHandlingTest) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test logging during signal handling + signal(SIGUSR1, SIG_IGN); + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages while sending signals + for (int i = 0; i < 1000; i++) { + if (i % 100 == 0) { + kill(getpid(), SIGUSR1); + } + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "Signal test message %d", i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 1000 messages with signals in %.3f seconds (%.0f messages/sec)\n", + elapsed, 1000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 10.0) << "Signal handling test should be reasonably fast"; +} + +// Test logging with error conditions +TEST_F(RDKLoggerPerformanceTest, ErrorConditionsTest) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages with various error conditions + for (int i = 0; i < 1000; i++) { + // Test with NULL parameters + rdk_logger_msg_printf(RDK_LOG_INFO, NULL, "NULL module test %d", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", NULL); + + // Test with invalid log levels + rdk_logger_msg_printf((rdk_LogLevel)999, "LOG.RDK.PERFORMANCE", "Invalid level test %d", i); + + // Test with empty strings + rdk_logger_msg_printf(RDK_LOG_INFO, "", "Empty module test %d", i); + //rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", ""); + + // Test with very long strings + char long_string[1000]; + memset(long_string, 'A', sizeof(long_string) - 1); + long_string[sizeof(long_string) - 1] = '\0'; + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", "Long string test %d: %s", i, long_string); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 5000 messages with error conditions in %.3f seconds (%.0f messages/sec)\n", + elapsed, 5000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 15.0) << "Error conditions test should be reasonably fast"; +} + +// Test logging with different output destinations +TEST_F(RDKLoggerPerformanceTest, DifferentOutputDestinationsTest) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages with different modules (different output destinations) + for (int i = 0; i < 1000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", "Performance module message %d", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.STRESS", "Stress module message %d", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.DEFAULT", "Default module message %d", i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 3000 messages with different destinations in %.3f seconds (%.0f messages/sec)\n", + elapsed, 3000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 10.0) << "Different output destinations test should be reasonably fast"; +} + +// Test logging with format string performance +TEST_F(RDKLoggerPerformanceTest, FormatStringPerformanceTest) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages with various format strings + for (int i = 0; i < 1000; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", + "Format test %d: %s %d %f %c %x %o %p %s %d %f", + i, "string", i, 3.14, 'A', i, i, &i, "another", i, 2.71); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 1000 messages with complex format strings in %.3f seconds (%.0f messages/sec)\n", + elapsed, 1000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 10.0) << "Format string performance test should be reasonably fast"; +} +// Test logging with onboard function performance +TEST_F(RDKLoggerPerformanceTest, OnboardFunctionPerformanceTest) { + rdk_Error ret = rdk_logger_init("/tmp/rdk_logger_performance_test/test.ini"); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + struct timeval start, end; + gettimeofday(&start, NULL); + + // Log messages using onboard function + for (int i = 0; i < 1000; i++) { + rdk_logger_log_onboard("LOG.RDK.PERFORMANCE", "Onboard test %d", i); + } + + gettimeofday(&end, NULL); + double elapsed = getTimeDifference(&start, &end); + + printf("Logged 1000 messages with onboard function in %.3f seconds (%.0f messages/sec)\n", + elapsed, 1000.0 / elapsed); + + // Should complete in reasonable time + EXPECT_LT(elapsed, 10.0) << "Onboard function performance test should be reasonably fast"; +} diff --git a/unittests/rdkLoggerRotationTest.cpp b/unittests/rdkLoggerRotationTest.cpp new file mode 100644 index 0000000..351b1b5 --- /dev/null +++ b/unittests/rdkLoggerRotationTest.cpp @@ -0,0 +1,422 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file + * the following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +/****************************************************** +Test Case : Testing RDK Logger Log Rotation Functionality +*******************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" + +class RDKLoggerRotationTest : public ::testing::Test { +protected: + void SetUp() override { + // Create test directory + system("mkdir -p /tmp/rdk_logger_rotation_test"); + + // Create test configuration file + createTestConfigFile("/tmp/rdk_logger_rotation_test/test.ini", + "LOG.RDK.DEFAULT=WARN\n" + "LOG.RDK.ROTATION=DEBUG\n"); + } + + void TearDown() override { + // Cleanup + system("rm -rf /tmp/rdk_logger_rotation_test"); + rdk_logger_deinit(); + } + + void createTestConfigFile(const char* filename, const char* content) { + FILE* file = fopen(filename, "w"); + if (file) { + fprintf(file, "%s", content); + fclose(file); + } + } + + long getFileSize(const char* filename) { + struct stat st; + if (stat(filename, &st) == 0) { + return st.st_size; + } + return -1; + } + + int countFilesInDirectory(const char* dirname) { + DIR* dir = opendir(dirname); + if (!dir) { + return -1; + } + + int count = 0; + struct dirent* entry; + while ((entry = readdir(dir)) != NULL) { + if (entry->d_name[0] != '.') { + printf("Found file: %s\n", entry->d_name); + count++; + } + } + closedir(dir); + return count; + } + + void createLargeLogMessage(char* buffer, size_t size) { + // Create a message that will fill the buffer + const char* base_message = "This is a test log message for rotation testing. "; + size_t base_len = strlen(base_message); + + size_t pos = 0; + while (pos < size - 1) { + size_t remaining = size - pos - 1; + size_t copy_len = (remaining > base_len) ? base_len : remaining; + memcpy(buffer + pos, base_message, copy_len); + pos += copy_len; + } + buffer[size - 1] = '\0'; + } +}; + +// Test extended initialization with log rotation +TEST_F(RDKLoggerRotationTest, ExtendedInitialization) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "test_rotation.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; // 1KB max size + config.maxCount = 3; // Keep 3 files + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; + + // Test that logging works + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Test message for rotation"); +} +// Test log rotation with count limits +TEST_F(RDKLoggerRotationTest, CountBasedRotation) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "count_test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 256; // 256 bytes max size + config.maxCount = 2; // Keep only 2 files + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; + + // Generate many log messages to trigger multiple rotations + char large_message[200]; + createLargeLogMessage(large_message, sizeof(large_message)); + + for (int i = 0; i < 20; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d: %s", i, large_message); + } + + // Check that only maxCount files exist + int file_count = countFilesInDirectory("/tmp/rdk_logger_rotation_test"); + printf("file_count : %d\n",file_count); + system("ls -lt /tmp/rdk_logger_rotation_test"); + EXPECT_LE(file_count, config.maxCount + 1) << "Should not exceed maxCount files"; +} +#if 0 +// Test log rotation with invalid configuration +TEST_F(RDKLoggerRotationTest, InvalidConfiguration) { + rdk_logger_ext_config_t config; + + // Test with NULL config + rdk_Error ret = rdk_logger_ext_init(NULL); + // Should handle gracefully + + // Test with empty file name + strncpy(config.fileName, "", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; + config.maxCount = 3; + + ret = rdk_logger_ext_init(&config); + // Should handle gracefully + + // Test with empty log directory + strncpy(config.fileName, "test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + ret = rdk_logger_ext_init(&config); + // Should handle gracefully +} +#endif +// Test log rotation with invalid directory +TEST_F(RDKLoggerRotationTest, InvalidDirectory) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/nonexistent/directory", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; + config.maxCount = 3; + + rdk_Error ret = rdk_logger_ext_init(&config); + // Should handle gracefully (may fail or create directory) +} + +// Test log rotation with very small size limits +TEST_F(RDKLoggerRotationTest, VerySmallSizeLimits) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "small_test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 10; // Very small size + config.maxCount = 2; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle very small size limits"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + } + + // Should handle gracefully +} + +// Test log rotation with very large size limits +TEST_F(RDKLoggerRotationTest, VeryLargeSizeLimits) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "large_test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024 * 1024 * 100; // 100MB + config.maxCount = 10; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle very large size limits"; + + // Generate some log messages + for (int i = 0; i < 10; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + } + + // Should handle gracefully +} + +// Test log rotation with zero count limits +TEST_F(RDKLoggerRotationTest, ZeroCountLimits) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "zero_count_test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; + config.maxCount = 0; // Zero count + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle zero count limits"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + } + + // Should handle gracefully +} + +// Test log rotation with negative values +TEST_F(RDKLoggerRotationTest, NegativeValues) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "negative_test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = -1; // Negative size + config.maxCount = -1; // Negative count + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle negative values"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + } + + // Should handle gracefully +} + +// Test log rotation with long file names +TEST_F(RDKLoggerRotationTest, LongFileNames) { + rdk_logger_ext_config_t config; + + // Create a very long file name + char long_filename[RDK_LOGGER_EXT_FILENAME_SIZE]; + memset(long_filename, 'A', sizeof(long_filename) - 5); + strcpy(long_filename + sizeof(long_filename) - 5, ".log"); + long_filename[sizeof(long_filename) - 1] = '\0'; + + strncpy(config.fileName, long_filename, sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; + config.maxCount = 3; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle long file names"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + } + + // Should handle gracefully +} + +// Test log rotation with long directory paths +TEST_F(RDKLoggerRotationTest, LongDirectoryPaths) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + // Create a very long directory path + char long_dir[RDK_LOGGER_EXT_LOGDIR_SIZE]; + memset(long_dir, 'A', sizeof(long_dir) - 1); + long_dir[sizeof(long_dir) - 1] = '\0'; + + strncpy(config.logdir, long_dir, sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; + config.maxCount = 3; + + rdk_Error ret = rdk_logger_ext_init(&config); + // Should handle gracefully (may fail due to path length) + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + } + + // Should handle gracefully +} + +// Test log rotation with special characters in file names +TEST_F(RDKLoggerRotationTest, SpecialCharactersInFileNames) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "test_file_with_special_chars.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; + config.maxCount = 3; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle special characters in file names"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + } + + // Should handle gracefully +} + +// Test log rotation with concurrent access +TEST_F(RDKLoggerRotationTest, ConcurrentAccess) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "concurrent_test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 512; + config.maxCount = 3; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; + + // Generate log messages rapidly to test concurrent access + for (int i = 0; i < 20; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Concurrent message %d", i); + rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.ROTATION", "Debug message %d", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.ROTATION", "Error message %d", i); + } + + // Should handle concurrent access gracefully +} +#if 0 +// Test log rotation with different log levels +TEST_F(RDKLoggerRotationTest, DifferentLogLevels) { + rdk_logger_ext_config_t config; + strncpy(config.fileName, "levels_test.log", sizeof(config.fileName) - 1); + config.fileName[sizeof(config.fileName) - 1] = '\0'; + + strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); + config.logdir[sizeof(config.logdir) - 1] = '\0'; + + config.maxSize = 1024; + config.maxCount = 3; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; + + // Test all log levels + rdk_logger_msg_printf(RDK_LOG_FATAL, "LOG.RDK.ROTATION", "Fatal message"); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.ROTATION", "Error message"); + rdk_logger_msg_printf(RDK_LOG_WARN, "LOG.RDK.ROTATION", "Warning message"); + rdk_logger_msg_printf(RDK_LOG_NOTICE, "LOG.RDK.ROTATION", "Notice message"); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Info message"); + rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.ROTATION", "Debug message"); + rdk_logger_msg_printf(RDK_LOG_TRACE, "LOG.RDK.ROTATION", "Trace message"); + + // Should handle all log levels correctly +} +#endif diff --git a/unittests/rdkLoggerStreamEnvTest.cpp b/unittests/rdkLoggerStreamEnvTest.cpp new file mode 100644 index 0000000..59079ad --- /dev/null +++ b/unittests/rdkLoggerStreamEnvTest.cpp @@ -0,0 +1,105 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file + * the following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#include +#include +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" +#include "log4c.h" + +TEST(StreamEnvOpenTest, SimplePath_NoEnvVars_Stdout) +{ + // Initialize logger first + char conf_file[] = GTEST_DEBUG_INI_FILE; + rdk_logger_init(conf_file); + + // Create a NEW appender (not opened yet, so fp will be NULL) + log4c_appender_t* appender = log4c_appender_new("stdout"); + ASSERT_NE(appender, nullptr) << "Failed to create appender"; + + // Set the type to stream_env (this registers the open callback) + log4c_appender_set_type(appender, log4c_appender_type_get("stream_env")); + + // Now open it - this will call stream_env_open with fp=NULL + // This WILL execute beyond line 615 because fp is NULL on first open + int ret = log4c_appender_open(appender); + EXPECT_EQ(ret, 0) << "stream_env_open should succeed"; + + // Verify the file pointer is set to stdout + FILE* fp = (FILE*)log4c_appender_get_udata(appender); + EXPECT_EQ(fp, stdout) << "File pointer should be stdout"; + + // Close the appender + log4c_appender_close(appender); +} + +TEST(StreamEnvOpenTest, EnvVariable_ValidPath_ParsesCorrectly) +{ + // Initialize logger + char conf_file[] = GTEST_DEBUG_INI_FILE; + rdk_logger_init(conf_file); + + // Set an environment variable for testing + setenv("RDK_TEST_LOG_DIR", "/tmp", 1); + + // Create appender with env var in name: $(RDK_TEST_LOG_DIR)/test.log + log4c_appender_t* appender = log4c_appender_new("$(RDK_TEST_LOG_DIR)/streamenv_test.log"); + ASSERT_NE(appender, nullptr) << "Failed to create appender"; + + // Use stream_env_append type (append=1 path) + log4c_appender_set_type(appender, log4c_appender_type_get("stream_env_append")); + + // Open - this parses $(RDK_TEST_LOG_DIR) and resolves to /tmp/streamenv_test.log + int ret = log4c_appender_open(appender); + EXPECT_EQ(ret, 0) << "stream_env_open should parse env var and succeed"; + + // Verify file pointer is not NULL and not stdout/stderr + FILE* fp = (FILE*)log4c_appender_get_udata(appender); + EXPECT_NE(fp, nullptr) << "File pointer should not be null"; + EXPECT_NE(fp, stdout) << "File pointer should not be stdout"; + EXPECT_NE(fp, stderr) << "File pointer should not be stderr"; + + // Close and cleanup + log4c_appender_close(appender); + unlink("/tmp/streamenv_test.log"); + unsetenv("RDK_TEST_LOG_DIR"); +} + +TEST(StreamEnvOpenTest, EnvVariable_NotFound_ReturnsError) +{ + // Initialize logger + char conf_file[] = GTEST_DEBUG_INI_FILE; + rdk_logger_init(conf_file); + + // Ensure the env var doesn't exist + unsetenv("RDK_NONEXISTENT_VAR_12345"); + + // Create appender with non-existent env var + log4c_appender_t* appender = log4c_appender_new("$(RDK_NONEXISTENT_VAR_12345)/test.log"); + ASSERT_NE(appender, nullptr) << "Failed to create appender"; + + log4c_appender_set_type(appender, log4c_appender_type_get("stream_env")); + + // Open should fail because getenv returns NULL + // This triggers: goto parse_error at line 641 + int ret = log4c_appender_open(appender); + EXPECT_EQ(ret, -1) << "stream_env_open should fail with parse error"; +} + diff --git a/unittests/rdkLoggerUtilityTest.cpp b/unittests/rdkLoggerUtilityTest.cpp new file mode 100644 index 0000000..6e7e667 --- /dev/null +++ b/unittests/rdkLoggerUtilityTest.cpp @@ -0,0 +1,60 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file + * the following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" +#include "rdk_logger_milestone.h" + + +TEST(RDKLoggerUtilityTest, LogOnboardFunctionality) { + char conf_file[] = GTEST_DEBUG_INI_FILE; + rdk_Error ret = rdk_logger_init(conf_file); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + // Test onboard logging + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Test onboard message"); + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Onboard message with format: %d", 123); + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Onboard message with multiple args: %s %d %f", "test", 456, 3.14); + logMilestone("APPLICATION_READY"); + + // Should work correctly +} +// Test rdk_logger_log_onboard with different log levels +TEST(RDKLoggerUtilityTest, LogOnboardDifferentLevels) { + char conf_file[] = GTEST_DEBUG_INI_FILE; + rdk_Error ret = rdk_logger_init(conf_file); + ASSERT_EQ(ret, RDK_SUCCESS) << "Failed to initialize logger"; + + // Test onboard logging with different message types + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Fatal onboard message"); + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Error onboard message"); + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Warning onboard message"); + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Notice onboard message"); + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Info onboard message"); + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Debug onboard message"); + rdk_logger_log_onboard("LOG.RDK.ONBOARD", "Trace onboard message"); + + // Should work correctly +} diff --git a/unittests/rdkloggerInit.cpp b/unittests/rdkloggerInit.cpp index b595f90..e3a68b5 100644 --- a/unittests/rdkloggerInit.cpp +++ b/unittests/rdkloggerInit.cpp @@ -27,12 +27,13 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf /*DIABLED some test cases as there's a bug "https://bugzilla.redhat.com/show_bug.cgi?id=1901955" in log4c library, calling log4c_init twice causing segmentation fault, hence keeping rdk_logger_deinit()'s default changes which does not allow calling rdk_logger_init twice*/ -TEST(rdkloggerInit, DISABLED_rdkLoggerInit_with_DebugConfFile) + +TEST(rdkloggerInit, rdkLoggerInit_with_DebugConfFile) { - rdk_Error ret = RDK_SUCCESS; + rdk_Error ret = -1; char *conf_file = NULL; ret = rdk_logger_init(conf_file); - ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_init failed with return:\""<name()); rdk_logger_msg_printf (RDK_LOG_INFO, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); rdk_logger_msg_printf (RDK_LOG_TRACE, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_logger_msg_printf (RDK_LOG_NONE, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_logger_msg_printf (RDK_LOG_NONE, NULL, "gtest case \"%s\"\n",test_info_->name()); //ret = rdk_logger_deinit(); //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" + + +TEST(rdkloggerMsgRaw, logModule_ONLYERROR_output_to_file) +{ + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + ret = rdk_logger_init(conf_file); + ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_init failed"<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.ONLYWARNING" , "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + rdk_dbg_MsgRaw (RDK_LOG_FATAL, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_WARN, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_NOTICE, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_DEBUG, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_INFO, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + rdk_dbg_MsgRaw (RDK_LOG_TRACE, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); +// ret = rdk_logger_deinit(); +// ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< +#include +#include +#include "rdk_logger.h" +#include "gtest_app.h" + +void gtest_rdk_dbg_MsgRaw1(rdk_LogLevel level, const char *mod, const char *format, ...) +{ + va_list args; + va_start(args, format); + rdk_dbg_MsgRaw1(level, mod, format, args); + va_end(args); +} + +TEST(rdkloggerMsgRaw1, logModule_ONLYFATAL_output_to_file) +{ + rdk_Error ret = RDK_SUCCESS; + char conf_file[] = GTEST_DEBUG_INI_FILE; + ret = rdk_logger_init(conf_file); + ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_init failed"<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ONLYFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ONLYFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ONLYFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ONLYFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ONLYFATAL", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ONLYWARNING" , "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ONLYWARNING", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ONLYINFO", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ONLYNOTICE", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.NODEBUG", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.NOERROR", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.NOWARNING", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.NONOTICE", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.NOTRACE", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.NOFATAL", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.NOALL", "gtest case \"%s\"\n",test_info_->name()); + //ret = rdk_logger_deinit(); + //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_FATAL, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_WARN, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_NOTICE, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_DEBUG, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_INFO, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); + gtest_rdk_dbg_MsgRaw1(RDK_LOG_TRACE, "LOG.RDK.ALLLOGLEVELS", "gtest case \"%s\"\n",test_info_->name()); +// ret = rdk_logger_deinit(); +// ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< Date: Thu, 30 Oct 2025 12:03:13 -0400 Subject: [PATCH 28/37] Revert "RDKEMW-8528: Remove logMilestone.sh & use the binary when needed (#28)" This reverts commit a0e24181c3e7243c99e9a53b35aae69f24da5cdb. --- scripts/logMilestone.sh | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 scripts/logMilestone.sh diff --git a/scripts/logMilestone.sh b/scripts/logMilestone.sh new file mode 100644 index 0000000..8d75122 --- /dev/null +++ b/scripts/logMilestone.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +########################################################################## +# If not stated otherwise in this file or this component's LICENSE +# file the following copyright and licenses apply: +# +# Copyright 2016 RDK Management +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +########################################################################## + +. /etc/include.properties + +export PATH=$PATH:/usr/bin:/bin:/usr/local/bin:/sbin:/usr/local/sbin +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib:/usr/lib/ + +if [ -z "$1" ]; +then + echo "Usage: `basename $0` " + exit 1 +fi +#rdkLogMileStone will give uptime info in milliseconds. +UPTIME_BIN="/usr/bin/rdkLogMileStone" + +MILESTONE_EVENT=$1 + +if [ -f "$UPTIME_BIN" ]; then + #write uptime using rdkLogMileStone binary + uptime=`$UPTIME_BIN $1` +else + echo "$UPTIME_BIN not found..!" + exit -1 +fi From aa09d85abed614966b88d75070521d2f62c7fc80 Mon Sep 17 00:00:00 2001 From: kamirt573_comcast Date: Fri, 31 Oct 2025 13:52:05 +0000 Subject: [PATCH 29/37] Release of v2.4.0 Signed-off-by: kamirt573_comcast --- CHANGELOG.md | 14 ++++++++++++++ configure.ac | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6309d4c..8c608b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,24 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v2.4.0](https://github.com/rdkcentral/rdk_logger/compare/v2.3.0...v2.4.0) + +- RDKEMW-6710: RDKLogger - Improve L1 Test coverage [`#31`](https://github.com/rdkcentral/rdk_logger/pull/31) +- RDKEMW-9247 : Moving rdklogger_milestone file from .cpp to .c [`#30`](https://github.com/rdkcentral/rdk_logger/pull/30) +- Update CODEOWNERS [`#29`](https://github.com/rdkcentral/rdk_logger/pull/29) +- RDKEMW-8528: Remove logMilestone.sh & use the binary when needed [`#28`](https://github.com/rdkcentral/rdk_logger/pull/28) +- RDKEMW-8798 : Post Code Coverage in the PR workflow [`#27`](https://github.com/rdkcentral/rdk_logger/pull/27) +- Deploy fossid_integration_stateless_diffscan_target_repo action [`#26`](https://github.com/rdkcentral/rdk_logger/pull/26) +- Revert "RDKEMW-8528: Remove logMilestone.sh & use the binary when needed (#28)" [`1daa6b4`](https://github.com/rdkcentral/rdk_logger/commit/1daa6b467a30c30dfaddff4451e3afe3e8290f24) +- Deploy cla action #15 [`761e339`](https://github.com/rdkcentral/rdk_logger/commit/761e3392383d2625f5d58ae2758f9fd31dcd45d3) + #### [v2.3.0](https://github.com/rdkcentral/rdk_logger/compare/v2.2.0...v2.3.0) +> 23 September 2025 + - Update Documentation for RDKLogger [`#24`](https://github.com/rdkcentral/rdk_logger/pull/24) - RDKB-61752 : Add Legacy Function for Backward Compatibility [`#23`](https://github.com/rdkcentral/rdk_logger/pull/23) +- Release of RDKLogger v2.3.0 [`92065f0`](https://github.com/rdkcentral/rdk_logger/commit/92065f0e648feb9fa2f696c77ec88560ae349fbd) #### [v2.2.0](https://github.com/rdkcentral/rdk_logger/compare/v2.1.0...v2.2.0) diff --git a/configure.ac b/configure.ac index ae73e34..030e1c5 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 2.3.0) +AC_INIT(rdklogger, 2.4.0) AC_CONFIG_SRCDIR([src]) AM_CONFIG_HEADER(cfg/config.h) AC_CONFIG_MACRO_DIR([cfg]) From cb6e34514060895d2eb300328ad6f307c809b9f9 Mon Sep 17 00:00:00 2001 From: rosemarybennyy Date: Tue, 11 Nov 2025 18:42:39 +0530 Subject: [PATCH 30/37] RDKEMW-9545: [RDKLogger] Post Code Current Coverage & the latest in the PR as Comment (#37) * RDKEMW-9545 : Post Code Current Coverage & the latest in the PR as Comment Reason for change: Post Code Current Coverage & the latest in the PR as Comment Test Procedure: Tested and verified Risks: Low Signed-off-by: RoseMary_Benny@comcast.com --- .github/workflows/L1-tests.yml | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index 5379edf..ac01351 100644 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -126,4 +126,40 @@ jobs: uses: actions/upload-artifact@v4 with: name: coverage-report - path: /tmp/coverage_report + path: /tmp/coverage_report + - name: Extract coverage summary + if: ${{ matrix.coverage == 'with-coverage' && github.event_name == 'pull_request' }} + id: coverage + run: | + lcov --list coverage.info + lcov --summary coverage.info >>log.txt + cat log.txt + LINE_COVERAGE=$(grep -m1 "lines" log.txt | awk '{print $2}') + FUNCTION_COVERAGE=$(grep -m1 "functions" log.txt | awk '{print $2}') + echo "line_coverage=${LINE_COVERAGE}" >> $GITHUB_OUTPUT + echo "function_coverage=${FUNCTION_COVERAGE}" >> $GITHUB_OUTPUT + echo "Check: Extracted for output: Line coverage: $LINE_COVERAGE" + echo "Check: Extracted for output: Function coverage: $FUNCTION_COVERAGE" + - name: Checkout PR + uses: actions/checkout@v3 + + - name: Run git fetch + id: lines_added + run : | + cd ${{ github.workspace }} + git fetch origin ${{ github.event.pull_request.base.ref }} + git fetch origin ${{ github.event.pull_request.head.ref }} + ADDED_LINES=$(git diff --unified=0 origin/${{ github.event.pull_request.base.ref }} origin/${{ github.event.pull_request.head.ref }} -- src/ | grep '^+' | grep -v '^+++' | wc -l) + echo "added_lines=${ADDED_LINES}" >> $GITHUB_OUTPUT + echo "check : added_lines $ADDED_LINES" + + - name: Post coverage comment on PR + if: ${{ matrix.coverage == 'with-coverage' && github.event_name == 'pull_request' }} + uses: peter-evans/create-or-update-comment@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.pull_request.number }} + body: | + Newly added lines compared to develop ✅ : ${{ steps.lines_added.outputs.added_lines }} + Line coverage ✅ : ${{ steps.coverage.outputs.line_coverage }} + Function coverage ✅ : ${{ steps.coverage.outputs.function_coverage }} From 8457a0a34f462bab4bd59f0992fe7261a2f9f99c Mon Sep 17 00:00:00 2001 From: Karunakaran A <48997923+karuna2git@users.noreply.github.com> Date: Wed, 12 Nov 2025 11:01:27 -0500 Subject: [PATCH 31/37] =?UTF-8?q?Revert=20"RDKEMW-9545:=20[RDKLogger]=20Po?= =?UTF-8?q?st=20Code=20Current=20Coverage=20&=20the=20latest=20in=20t?= =?UTF-8?q?=E2=80=A6"=20(#38)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit cb6e34514060895d2eb300328ad6f307c809b9f9. --- .github/workflows/L1-tests.yml | 38 +--------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/.github/workflows/L1-tests.yml b/.github/workflows/L1-tests.yml index ac01351..5379edf 100644 --- a/.github/workflows/L1-tests.yml +++ b/.github/workflows/L1-tests.yml @@ -126,40 +126,4 @@ jobs: uses: actions/upload-artifact@v4 with: name: coverage-report - path: /tmp/coverage_report - - name: Extract coverage summary - if: ${{ matrix.coverage == 'with-coverage' && github.event_name == 'pull_request' }} - id: coverage - run: | - lcov --list coverage.info - lcov --summary coverage.info >>log.txt - cat log.txt - LINE_COVERAGE=$(grep -m1 "lines" log.txt | awk '{print $2}') - FUNCTION_COVERAGE=$(grep -m1 "functions" log.txt | awk '{print $2}') - echo "line_coverage=${LINE_COVERAGE}" >> $GITHUB_OUTPUT - echo "function_coverage=${FUNCTION_COVERAGE}" >> $GITHUB_OUTPUT - echo "Check: Extracted for output: Line coverage: $LINE_COVERAGE" - echo "Check: Extracted for output: Function coverage: $FUNCTION_COVERAGE" - - name: Checkout PR - uses: actions/checkout@v3 - - - name: Run git fetch - id: lines_added - run : | - cd ${{ github.workspace }} - git fetch origin ${{ github.event.pull_request.base.ref }} - git fetch origin ${{ github.event.pull_request.head.ref }} - ADDED_LINES=$(git diff --unified=0 origin/${{ github.event.pull_request.base.ref }} origin/${{ github.event.pull_request.head.ref }} -- src/ | grep '^+' | grep -v '^+++' | wc -l) - echo "added_lines=${ADDED_LINES}" >> $GITHUB_OUTPUT - echo "check : added_lines $ADDED_LINES" - - - name: Post coverage comment on PR - if: ${{ matrix.coverage == 'with-coverage' && github.event_name == 'pull_request' }} - uses: peter-evans/create-or-update-comment@v3 - with: - token: ${{ secrets.GITHUB_TOKEN }} - issue-number: ${{ github.event.pull_request.number }} - body: | - Newly added lines compared to develop ✅ : ${{ steps.lines_added.outputs.added_lines }} - Line coverage ✅ : ${{ steps.coverage.outputs.line_coverage }} - Function coverage ✅ : ${{ steps.coverage.outputs.function_coverage }} + path: /tmp/coverage_report From 2f4ae96a67c82aa51326171e5a03a89b786127b7 Mon Sep 17 00:00:00 2001 From: Deepthi C Shetty <115452109+dshett549@users.noreply.github.com> Date: Fri, 19 Dec 2025 22:34:37 +0530 Subject: [PATCH 32/37] RDKEMW-10792: Extending logger_init function to set level, format and output type (#41) * RDKEMW-10792: Extending logger_init function to set level, format and output type Reason for change: Extending logger_init function to set level, format and output type Risks:Medium Priority:P1 Signed-off-by: dshett549 Co-authored-by: Karunakaran A <48997923+karuna2git@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- include/rdk_error.h | 4 +- include/rdk_logger.h | 68 ++- src/include/rdk_debug_priv.h | 5 +- src/rdk_debug_priv.c | 216 ++++++++-- src/rdk_dynamic_logger.c | 7 +- src/rdk_logger_init.c | 27 +- unittests/CMakeLists.txt | 1 + unittests/main.cpp | 5 +- unittests/rdkLoggerPerformanceTest.cpp | 35 +- unittests/rdkLoggerRotationTest.cpp | 568 ++++++++++++++----------- unittests/test_rdkloggerExtInit.cpp | 111 +++++ unittests/test_utils.h | 27 ++ 12 files changed, 754 insertions(+), 320 deletions(-) create mode 100644 unittests/test_rdkloggerExtInit.cpp create mode 100644 unittests/test_utils.h diff --git a/include/rdk_error.h b/include/rdk_error.h index adaefce..991f091 100644 --- a/include/rdk_error.h +++ b/include/rdk_error.h @@ -30,8 +30,8 @@ typedef unsigned int uint32_t; #endif #define RDK_SUCCESS 0 - -typedef uint32_t rdk_Error; +#define RDK_FAILURE -1 +typedef int32_t rdk_Error; #ifdef __cplusplus diff --git a/include/rdk_logger.h b/include/rdk_logger.h index 12cb3ba..59ad121 100644 --- a/include/rdk_logger.h +++ b/include/rdk_logger.h @@ -153,12 +153,12 @@ extern "C" /** * Define the max length for the log file capture */ -#define RDK_LOGGER_EXT_FILENAME_SIZE 32 +#define RDK_LOGGER_EXT_FILENAME_SIZE 64 /** * Define the max length for the log capture path */ -#define RDK_LOGGER_EXT_LOGDIR_SIZE 32 +#define RDK_LOGGER_EXT_LOGDIR_SIZE 256 /** * To allow compatibility of mutiple legacy RDK components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 @@ -200,13 +200,65 @@ typedef enum RDK_LOG_NONE } rdk_LogLevel; +/** + * @enum rdk_LogOutput + * @brief Defines the destination type where log events are written. + * + * - RDKLOG_OUTPUT_CONSOLE: Write logs to the process stdout/stderr stream (typically mapped via stream_env). + * - RDKLOG_OUTPUT_FILE: Write logs to rolling files on disk (uses rollingfile appender). + * - RDKLOG_OUTPUT_SYSLOG: Forward logs to the local syslog daemon. + */ +typedef enum +{ + RDKLOG_OUTPUT_CONSOLE = 0, + RDKLOG_OUTPUT_SYSLOG, + RDKLOG_OUTPUT_FILE +} rdk_LogOutput; + +/** + * @enum rdk_LogFormat + * @brief Defines the layout/format used to render log messages. + * + * - RDKLOG_FORMAT_ONLY_TEXT: Simple layout (priority, category, message). + * - RDKLOG_FORMAT_WITH_DATETIME: Timestamped layout including date/time and milliseconds. + * - RDKLOG_FORMAT_WITH_THREADID: Comcast-specific dated layout with the exact fields + * (such as module, level, thread id, etc.) + * depend on the configured layout implementation. + */ +typedef enum +{ + RDKLOG_FORMAT_ONLY_TEXT = 0, + RDKLOG_FORMAT_WITH_DATETIME, + RDKLOG_FORMAT_WITH_THREADID +} rdk_LogFormat; + +/** + * @brief rdk_LogOutput_File structure for rolling file appenders. + * + * This structure defines the configuration parameters for file-based log appenders + * including file naming, directory path, and rotation policy settings. + */ +typedef struct rdk_LogOutput_File +{ + char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; + char fileLocation[RDK_LOGGER_EXT_LOGDIR_SIZE]; + int8_t fileCountMax; + int64_t fileSizeMax; +} rdk_LogOutput_File; +/** + * @brief Complete logger configuration structure for structured initialization. + * + * This structure contains all parameters needed for complete logger setup + * including appender configuration, category association, and log level settings. + */ typedef struct rdk_logger_ext_config_t - { - char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; - char logdir[RDK_LOGGER_EXT_LOGDIR_SIZE]; - long maxSize; - long maxCount; - }rdk_logger_ext_config_t; +{ + char* pCategoryName; /**< Log category name (e.g., "LOG.RDK.TR69") */ + rdk_LogLevel loglevel; /**< Default log level for this category */ + rdk_LogOutput appender; /**< Type of appender */ + rdk_LogFormat layout; /**< Message layout format */ + rdk_LogOutput_File *pFilePolicy; /**< File policy configuration (required for RDKLOG_OUTPUT_FILE, NULL for others) */ +} rdk_logger_ext_config_t; /** * @brief Initialize the RDK Logger. diff --git a/src/include/rdk_debug_priv.h b/src/include/rdk_debug_priv.h index 57fe31c..d20e5f4 100644 --- a/src/include/rdk_debug_priv.h +++ b/src/include/rdk_debug_priv.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" @@ -31,8 +33,7 @@ extern "C" void rdk_dbg_priv_init(void); void rdk_dbg_priv_config(void); -void rdk_dbg_priv_deinit(void); -void rdk_dbg_priv_ext_init(const char* logdir, const char* log_file_name, long maxCount, long maxSize); +rdk_Error rdk_dbg_priv_ext_init(const rdk_logger_ext_config_t* config); void rdk_dbg_priv_shutdown(); void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args); diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index 59f0ca2..ec2ece7 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -155,50 +155,191 @@ void rdk_dbg_priv_init() gRootCat = log4c_category_get("LOG.RDK"); } -void rdk_dbg_priv_ext_init(const char* logdir, const char* log_file_name, long maxCount, long maxSize) +static log4c_appender_t* rdk_dbg_priv_appender_init(const char* categoryName, rdk_LogOutput app, + rdk_LogFormat layout, rdk_LogOutput_File *pPolicy) { - char fullpath[512]; - snprintf(fullpath, sizeof(fullpath), "%s/%s", logdir, log_file_name); + char app_name[256]; - const char* cat_name = "LOG.RDK"; - log4c_category_t* cat = log4c_category_get(cat_name); - if (!cat) { - cat = log4c_category_new(cat_name); + if (!categoryName) + { + fprintf(stderr, "Error: categoryName is NULL\n"); + return NULL; } - log4c_appender_t* app = log4c_appender_get(fullpath); - if (!app) { - app = log4c_appender_new(fullpath); + if (app == RDKLOG_OUTPUT_FILE && pPolicy) + { + snprintf(app_name, sizeof(app_name), "%s.app", categoryName); + } + else + { + snprintf(app_name, sizeof(app_name), "%s.stdout", categoryName); } - log4c_appender_set_type(app, log4c_appender_type_get("rollingfile")); - rollingfile_udata_t *rudata = rollingfile_make_udata(); - rollingfile_udata_set_logdir(rudata, logdir); - rollingfile_udata_set_files_prefix(rudata, log_file_name); + log4c_appender_t* appender = log4c_appender_get(app_name); + if (appender) + { + (void)log4c_appender_close(appender); + (void)log4c_appender_set_udata(appender, NULL); + } + else + { + appender = log4c_appender_new(app_name); + if (!appender) + { + fprintf(stderr, "Failed to create appender %s\n", app_name); + return NULL; + } + } + + const char* type_str = NULL; + switch (app) + { + case RDKLOG_OUTPUT_CONSOLE: type_str = "stream_env"; break; + case RDKLOG_OUTPUT_FILE: type_str = "rollingfile"; break; + case RDKLOG_OUTPUT_SYSLOG: type_str = "syslog"; break; + default: type_str = "stream_env"; break; + } - log4c_rollingpolicy_t *policy = log4c_rollingpolicy_get(cat_name); - if (!policy) { - policy = log4c_rollingpolicy_new(cat_name); + const log4c_appender_type_t* type = log4c_appender_type_get(type_str); + if (type) + { + log4c_appender_set_type(appender, type); } - log4c_rollingpolicy_set_type(policy, log4c_rollingpolicy_type_get("sizewin")); - rollingpolicy_sizewin_udata_t *sizewin_udata = sizewin_make_udata(); - sizewin_udata_set_file_maxsize(sizewin_udata, maxSize); - sizewin_udata_set_max_num_files(sizewin_udata, maxCount); - log4c_rollingpolicy_set_udata(policy, sizewin_udata); + if (app == RDKLOG_OUTPUT_FILE && pPolicy) + { + rollingfile_udata_t *rudata = rollingfile_make_udata(); + if (rudata && pPolicy->fileLocation && pPolicy->fileName) + { + rollingfile_udata_set_logdir(rudata, pPolicy->fileLocation); + rollingfile_udata_set_files_prefix(rudata, pPolicy->fileName); + long maxBytes = (pPolicy->fileSizeMax > 0) ? pPolicy->fileSizeMax : 1024 * 1024; + + char policy_name[256]; + snprintf(policy_name, sizeof(policy_name), "policy_%s", log4c_appender_get_name(appender)); + if (pPolicy->fileCountMax > 0) + { + log4c_rollingpolicy_t *policy = log4c_rollingpolicy_get(policy_name); + if (!policy) + { + policy = log4c_rollingpolicy_new(policy_name); + } + + if (policy) + { + const log4c_rollingpolicy_type_t* rtype = log4c_rollingpolicy_type_get("sizewin"); + if (rtype) + { + log4c_rollingpolicy_set_type(policy, rtype); + } + + rollingpolicy_sizewin_udata_t *sizewin_udata = sizewin_make_udata(); + if (sizewin_udata) + { + sizewin_udata_set_file_maxsize(sizewin_udata, maxBytes); + sizewin_udata_set_max_num_files(sizewin_udata, pPolicy->fileCountMax); + log4c_rollingpolicy_set_udata(policy, sizewin_udata); + } + rollingfile_udata_set_policy(rudata, policy); + } + } + log4c_appender_set_udata(appender, rudata); + } + else + { + fprintf(stderr, "ruData or logdir or fileName is NULL\n"); + return NULL; + } + } + + const char* layout_str = NULL; + switch (layout) + { + case RDKLOG_FORMAT_ONLY_TEXT: layout_str = "basic"; break; + case RDKLOG_FORMAT_WITH_DATETIME: layout_str = "dated"; break; + case RDKLOG_FORMAT_WITH_THREADID: layout_str = "comcast_dated"; break; + default: layout_str = "basic"; break; + } - rollingfile_udata_set_policy(rudata, policy); - log4c_appender_set_udata(app, rudata); + log4c_layout_t* layout_obj = log4c_layout_get(layout_str); + if (layout_obj) + { + log4c_appender_set_layout(appender, layout_obj); + } - log4c_layout_t* layout = log4c_layout_get("comcast_dated"); - log4c_appender_set_layout(app, layout); + if (log4c_appender_open(appender) != 0) + { + fprintf(stderr, "log4c_appender_open failed for %s\n", app_name); + return NULL; + } - log4c_category_set_appender(cat, app); + return appender; } -void rdk_dbg_priv_deinit() +static rdk_Error rdk_dbg_priv_set_log_level(const char* category_name, rdk_LogLevel log_level) { - gRootCat = NULL; + const char* cat_name = category_name ? category_name : "LOG.RDK"; + log4c_category_t* cat = log4c_category_get(cat_name); + if (!cat) + { + cat = log4c_category_new(cat_name); + } + if (cat) + { + int log4c_prio = rdk_logLevel_to_log4c_priority(log_level); + log4c_category_set_priority(cat, log4c_prio); + } + return RDK_SUCCESS; +} +/** + * @brief Initialize RDK logger with extended configuration. + * This is the ONLY public API for extended logger initialization. + */ +rdk_Error rdk_dbg_priv_ext_init(const rdk_logger_ext_config_t* config) +{ + char appender_name[256]; + + if (!config) + { + fprintf(stderr, "Error: config parameter is NULL\n"); + return RDK_FAILURE; + } + const char* cat_name = config->pCategoryName ? config->pCategoryName : "LOG.RDK"; + log4c_category_t* cat = log4c_category_get(cat_name); + if (!cat) + cat = log4c_category_new(cat_name); + if (!cat) + cat = gRootCat; + if (!cat) + { + fprintf(stderr, "Failed to get or create log category\n"); + return RDK_FAILURE; + } + + if (config->appender == RDKLOG_OUTPUT_FILE && config->pFilePolicy == NULL) + { + fprintf(stderr, "Error: file appender requires non-NULL file policy\n"); + return RDK_FAILURE; + } + + log4c_appender_t* appender = rdk_dbg_priv_appender_init(cat_name, config->appender, + config->layout, config->pFilePolicy); + if (appender == NULL) + { + fprintf(stderr, "Failed to initialize appender for category %s\n", cat_name); + return RDK_FAILURE; + } + log4c_category_set_appender(cat, appender); + log4c_category_set_additivity(cat, 0); + + rdk_Error result = rdk_dbg_priv_set_log_level(cat_name, config->loglevel); + if(result != RDK_SUCCESS) + { + fprintf(stderr, "Failed to set log level for category %s\n", cat_name); + return result; + } + + return RDK_SUCCESS; } /** @@ -298,7 +439,7 @@ void rdk_dbg_priv_config(void) } gRootPriority = log4c_category_get_priority(gRootCat); } - else + else { printf("LOG.RDK.DEFAULT is not defined..\n"); return; @@ -366,13 +507,20 @@ void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const cha /* Handling process request here. This is not a blocking call and it shall return immediately */ rdk_dyn_log_process_pending_request(); + + if (!format) + { + fprintf(stderr, "Error: NULL format string passed to rdk_dbg_priv_log_msg\n"); + return; + } + cat = log4c_category_get(module_name); prio = log4c_category_get_priority(cat); if (cat && prio == LOG4C_PRIORITY_NOTSET && gRootCat) { - log4c_category_set_priority(cat, gRootPriority); + log4c_category_set_priority(cat, log4c_category_get_priority(gRootCat)); prio = gRootPriority; } - + if(!cat) { cat = gRootCat; @@ -662,6 +810,9 @@ static int stream_env_open(log4c_appender_t* appender, int append) fp = stderr; else if (!strcmp(newName,"stdout")) fp = stdout; + else if (strlen(newName) >= strlen(".stdout") && + strcmp(newName + strlen(newName) - strlen(".stdout"), ".stdout") == 0) + fp = stdout; else if (append) { printf("****Opening %s in append mode\n", newName); @@ -804,4 +955,3 @@ static int stream_env_close(log4c_appender_t* appender) return fclose(fp); } - diff --git a/src/rdk_dynamic_logger.c b/src/rdk_dynamic_logger.c index a60f5d2..95de593 100644 --- a/src/rdk_dynamic_logger.c +++ b/src/rdk_dynamic_logger.c @@ -181,7 +181,10 @@ void rdk_dyn_log_init() void rdk_dyn_log_deinit() { - close(g_dl_socket); - g_dl_socket = -1; + if (g_dl_socket != -1) + { + close(g_dl_socket); + g_dl_socket = -1; + } } diff --git a/src/rdk_logger_init.c b/src/rdk_logger_init.c index 87358a6..283ab42 100644 --- a/src/rdk_logger_init.c +++ b/src/rdk_logger_init.c @@ -40,7 +40,6 @@ #include "rdk_debug_priv.h" #include "rdk_dynamic_logger.h" #include "rdk_utils.h" - #define BUF_LEN 256 static int isLogInited = 0; /** @@ -89,13 +88,35 @@ rdk_Error rdk_logger_init(const char* debugConfigFile) return RDK_SUCCESS; } +/** + * @brief Initialize RDK logger with extended configuration. + * + * This function provides a comprehensive logger initialization interface that combines + * the standard RDK logger initialization with extended configuration options. It first + * calls RDK_LOGGER_INIT() to perform basic logger setup, then applies the extended + * configuration parameters for specific module logging requirements. + * + * @param[in] config Pointer to extended logger configuration structure containing: + * - pCategoryName: Log category/module name (required, cannot be NULL) + * - loglevel: Default log level for the category + * - appender: Type of log appender + * - layout: Message layout format + * - pFilePolicy: File policy configuration (required for file appenders, NULL for others) + * + * @return RDK_SUCCESS on successful initialization, RDK_FAILURE on error. + * + * @note This function must be called after the basic RDK logger system is available. + * @note If RDK_LOGGER_INIT() fails, the extended configuration is not applied. + * @note For file appenders, ensure the log directory exists and has write permissions. + * @note This function internally calls rdk_dbg_priv_ext_init() for the actual configuration. + */ rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config) - { +{ rdk_Error ret; ret = RDK_LOGGER_INIT(); if (ret == RDK_SUCCESS) { - rdk_dbg_priv_ext_init(config->logdir, config->fileName, config->maxCount, config->maxSize); + ret = rdk_dbg_priv_ext_init(config); } return ret; } diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 77b246a..3e83230 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -40,6 +40,7 @@ add_executable( rdkLoggerConfigTest.cpp rdkEnableLogLevel.cpp rdkLogLevelFromString.cpp + test_rdkloggerExtInit.cpp rdkLoggerRotationTest.cpp rdkLoggerErrorTest.cpp rdkLoggerPerformanceTest.cpp diff --git a/unittests/main.cpp b/unittests/main.cpp index e5973bb..53a68bb 100644 --- a/unittests/main.cpp +++ b/unittests/main.cpp @@ -29,7 +29,8 @@ GTEST_API_ int main(int argc, char* argv[]) ret = RUN_ALL_TESTS(); if(ret) + { printf("Gtest returned with error : %d !!!\n",ret); - - return 0; + } + return ret; } diff --git a/unittests/rdkLoggerPerformanceTest.cpp b/unittests/rdkLoggerPerformanceTest.cpp index 53f6823..3e07a7f 100644 --- a/unittests/rdkLoggerPerformanceTest.cpp +++ b/unittests/rdkLoggerPerformanceTest.cpp @@ -213,16 +213,16 @@ TEST_F(RDKLoggerPerformanceTest, RapidCallsPerformance) { // Log messages rapidly for (int i = 0; i < 5000; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", "Rapid message %d", i); - rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.PERFORMANCE", "Rapid debug %d", i); - rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.PERFORMANCE", "Rapid error %d", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.PERFORMANCE", "Rapid message %d\n", i); + rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.PERFORMANCE", "Rapid debug %d\n", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.PERFORMANCE", "Rapid error %d\n", i); } gettimeofday(&end, NULL); double elapsed = getTimeDifference(&start, &end); - printf("Logged 15000 rapid messages in %.3f seconds (%.0f messages/sec)\n", - elapsed, 15000.0 / elapsed); + printf("Logged 5000 rapid messages in %.3f seconds (%.0f messages/sec)\n", + elapsed, 5000.0 / elapsed); // Should complete in reasonable time EXPECT_LT(elapsed, 15.0) << "Rapid logging should be reasonably fast"; @@ -276,17 +276,22 @@ TEST_F(RDKLoggerPerformanceTest, CPUUsageTest) { // Test logging with file I/O stress TEST_F(RDKLoggerPerformanceTest, FileIOStressTest) { + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "stress_test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_performance_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; // 1KB + testPolicy.fileCountMax = 5; rdk_logger_ext_config_t config; - strncpy(config.fileName, "stress_test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_performance_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; // 1KB max size to trigger rotation - config.maxCount = 5; // Keep 5 files - - rdk_Error ret = rdk_logger_ext_init(&config); + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.PERFORMANCE"; + config.loglevel = RDK_LOG_DEBUG; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + + int32_t ret = rdk_logger_ext_init(&config); ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; struct timeval start, end; diff --git a/unittests/rdkLoggerRotationTest.cpp b/unittests/rdkLoggerRotationTest.cpp index 351b1b5..87b6bf3 100644 --- a/unittests/rdkLoggerRotationTest.cpp +++ b/unittests/rdkLoggerRotationTest.cpp @@ -23,6 +23,7 @@ Test Case : Testing RDK Logger Log Rotation Functionality #include #include #include +#include #include #include #include @@ -30,7 +31,7 @@ Test Case : Testing RDK Logger Log Rotation Functionality #include #include "rdk_logger.h" #include "gtest_app.h" - +#include "test_utils.h" class RDKLoggerRotationTest : public ::testing::Test { protected: void SetUp() override { @@ -101,295 +102,356 @@ class RDKLoggerRotationTest : public ::testing::Test { // Test extended initialization with log rotation TEST_F(RDKLoggerRotationTest, ExtendedInitialization) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "test_rotation.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; // 1KB max size - config.maxCount = 3; // Keep 3 files - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; - - // Test that logging works - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Test message for rotation"); + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "test_rotation.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; // 1KB + testPolicy.fileCountMax = 3; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_TRACE; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; + + // Test that logging works + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Test message for rotation"); + }); } -// Test log rotation with count limits + TEST_F(RDKLoggerRotationTest, CountBasedRotation) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "count_test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 256; // 256 bytes max size - config.maxCount = 2; // Keep only 2 files - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; - - // Generate many log messages to trigger multiple rotations - char large_message[200]; - createLargeLogMessage(large_message, sizeof(large_message)); - - for (int i = 0; i < 20; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d: %s", i, large_message); - } - - // Check that only maxCount files exist - int file_count = countFilesInDirectory("/tmp/rdk_logger_rotation_test"); - printf("file_count : %d\n",file_count); - system("ls -lt /tmp/rdk_logger_rotation_test"); - EXPECT_LE(file_count, config.maxCount + 1) << "Should not exceed maxCount files"; + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "count_test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 256; // 256 Bytes + testPolicy.fileCountMax = 2; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_TRACE; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; + + // Generate many log messages to trigger multiple rotations + char large_message[200]; + createLargeLogMessage(large_message, sizeof(large_message)); + + for (int i = 0; i < 20; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d: %s", i, large_message); + usleep(10000); // 10ms delay to avoid excessively long test runtime + } + + // Check that only maxCount files exist + int file_count = countFilesInDirectory("/tmp/rdk_logger_rotation_test"); + printf("file_count : %d\n",file_count); + system("ls -lt /tmp/rdk_logger_rotation_test"); + EXPECT_LE(file_count, testPolicy.fileCountMax + 1) << "Should not exceed maxCount files"; + }); } #if 0 // Test log rotation with invalid configuration -TEST_F(RDKLoggerRotationTest, InvalidConfiguration) { - rdk_logger_ext_config_t config; - - // Test with NULL config - rdk_Error ret = rdk_logger_ext_init(NULL); - // Should handle gracefully - - // Test with empty file name - strncpy(config.fileName, "", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; - config.maxCount = 3; - - ret = rdk_logger_ext_init(&config); - // Should handle gracefully - - // Test with empty log directory - strncpy(config.fileName, "test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - ret = rdk_logger_ext_init(&config); - // Should handle gracefully +TEST_F(RDKLoggerRotationTest, InvalidConfiguration) +{ + RUN_IN_FORK({ + rdk_Error err = rdk_logger_ext_init(NULL); + EXPECT_EQ(-1, (int)err)<<"EXT_INIT failed"; + + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; // 1KB + testPolicy.fileCountMax = 3; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_ERROR; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + + err = rdk_logger_ext_init(&config); + EXPECT_EQ(-1, (int)err)<<"EXT_INIT failed"; + }); } #endif // Test log rotation with invalid directory TEST_F(RDKLoggerRotationTest, InvalidDirectory) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/nonexistent/directory", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; - config.maxCount = 3; - - rdk_Error ret = rdk_logger_ext_init(&config); - // Should handle gracefully (may fail or create directory) + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/nonexistent/directory", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; // 1KB + testPolicy.fileCountMax = 3; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_ERROR; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&config); + // Should handle gracefully (may fail or create directory) + }); } // Test log rotation with very small size limits TEST_F(RDKLoggerRotationTest, VerySmallSizeLimits) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "small_test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 10; // Very small size - config.maxCount = 2; - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle very small size limits"; - - // Generate log messages - for (int i = 0; i < 5; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); - } - + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "small_test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 10; // 10 bytes + testPolicy.fileCountMax = 2; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_INFO; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle very small size limits"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + sleep(1); + } + }); // Should handle gracefully } // Test log rotation with very large size limits TEST_F(RDKLoggerRotationTest, VeryLargeSizeLimits) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "large_test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024 * 1024 * 100; // 100MB - config.maxCount = 10; - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle very large size limits"; - - // Generate some log messages - for (int i = 0; i < 10; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); - } - + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "large_test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024*1024*100; // 100MB + testPolicy.fileCountMax = 10; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_INFO; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_THREADID; + config.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle very large size limits"; + printf("ext_init succes\n"); + // Generate some log messages + for (int i = 0; i < 10; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + sleep(1); + printf("Iteration:%d\n",i); + } + }); // Should handle gracefully } // Test log rotation with zero count limits TEST_F(RDKLoggerRotationTest, ZeroCountLimits) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "zero_count_test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; - config.maxCount = 0; // Zero count - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle zero count limits"; - - // Generate log messages - for (int i = 0; i < 5; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); - } - + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "zero_count_test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; // 1KB + testPolicy.fileCountMax = 0; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_INFO; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_ONLY_TEXT; + config.pFilePolicy = &testPolicy; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle zero count limits"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + sleep(1); + } + }); // Should handle gracefully } // Test log rotation with negative values TEST_F(RDKLoggerRotationTest, NegativeValues) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "negative_test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = -1; // Negative size - config.maxCount = -1; // Negative count - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle negative values"; - - // Generate log messages - for (int i = 0; i < 5; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); - } - + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "negative_test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = -1; + testPolicy.fileCountMax = -1; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_INFO; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "negative values"; + + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + sleep(1); + } + }); // Should handle gracefully } - // Test log rotation with long file names TEST_F(RDKLoggerRotationTest, LongFileNames) { - rdk_logger_ext_config_t config; - - // Create a very long file name - char long_filename[RDK_LOGGER_EXT_FILENAME_SIZE]; - memset(long_filename, 'A', sizeof(long_filename) - 5); - strcpy(long_filename + sizeof(long_filename) - 5, ".log"); - long_filename[sizeof(long_filename) - 1] = '\0'; - - strncpy(config.fileName, long_filename, sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; - config.maxCount = 3; - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle long file names"; - - // Generate log messages - for (int i = 0; i < 5; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); - } - + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + // Create a very long file name + char long_filename[RDK_LOGGER_EXT_FILENAME_SIZE]; + memset(long_filename, 'A', sizeof(long_filename) - 5); + strcpy(long_filename + sizeof(long_filename) - 5, ".log"); + long_filename[sizeof(long_filename) - 1] = '\0'; + + strncpy(testPolicy.fileName, long_filename, sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; // 1KB + testPolicy.fileCountMax = 3; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_TRACE; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle long file names"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + sleep(1); + } + }); // Should handle gracefully } // Test log rotation with long directory paths TEST_F(RDKLoggerRotationTest, LongDirectoryPaths) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - // Create a very long directory path - char long_dir[RDK_LOGGER_EXT_LOGDIR_SIZE]; - memset(long_dir, 'A', sizeof(long_dir) - 1); - long_dir[sizeof(long_dir) - 1] = '\0'; - - strncpy(config.logdir, long_dir, sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; - config.maxCount = 3; - - rdk_Error ret = rdk_logger_ext_init(&config); - // Should handle gracefully (may fail due to path length) - - // Generate log messages - for (int i = 0; i < 5; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); - } - + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + char long_dir[RDK_LOGGER_EXT_LOGDIR_SIZE]; + memset(long_dir, 'A', sizeof(long_dir) - 1); + long_dir[sizeof(long_dir) - 1] = '\0'; + + strncpy(testPolicy.fileLocation, long_dir, sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; // 1 KB + testPolicy.fileCountMax = 3; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_TRACE; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&config); + // Should handle gracefully (may fail due to path length) + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + sleep(1); + } + }); // Should handle gracefully } - // Test log rotation with special characters in file names TEST_F(RDKLoggerRotationTest, SpecialCharactersInFileNames) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "test_file_with_special_chars.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; - config.maxCount = 3; - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle special characters in file names"; - - // Generate log messages - for (int i = 0; i < 5; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); - } - + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "test_file_with_special_chars.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; // 1 KB + testPolicy.fileCountMax = 3; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_TRACE; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_ONLY_TEXT; + config.pFilePolicy = &testPolicy; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Should handle special characters in file names"; + + // Generate log messages + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Message %d", i); + sleep(1); + } + }); // Should handle gracefully } // Test log rotation with concurrent access TEST_F(RDKLoggerRotationTest, ConcurrentAccess) { - rdk_logger_ext_config_t config; - strncpy(config.fileName, "concurrent_test.log", sizeof(config.fileName) - 1); - config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 512; - config.maxCount = 3; - - rdk_Error ret = rdk_logger_ext_init(&config); - ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; - - // Generate log messages rapidly to test concurrent access - for (int i = 0; i < 20; i++) { - rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Concurrent message %d", i); - rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.ROTATION", "Debug message %d", i); - rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.ROTATION", "Error message %d", i); - } - + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "concurrent_test.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 512; // 512 Bytes + testPolicy.fileCountMax = 3; + rdk_logger_ext_config_t config; + memset(&config, 0, sizeof(config)); + config.pCategoryName = "LOG.RDK.ROTATION"; + config.loglevel = RDK_LOG_DEBUG; + config.appender = RDKLOG_OUTPUT_FILE; + config.layout = RDKLOG_FORMAT_WITH_DATETIME; + config.pFilePolicy = &testPolicy; + + rdk_Error ret = rdk_logger_ext_init(&config); + ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; + + // Generate log messages rapidly to test concurrent access + for (int i = 0; i < 20; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Concurrent message %d", i); + rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.ROTATION", "Debug message %d", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.ROTATION", "Error message %d", i); + usleep(10000); // 10 ms delay instead of 1 second to keep test fast + } + }); // Should handle concurrent access gracefully } #if 0 @@ -398,16 +460,16 @@ TEST_F(RDKLoggerRotationTest, DifferentLogLevels) { rdk_logger_ext_config_t config; strncpy(config.fileName, "levels_test.log", sizeof(config.fileName) - 1); config.fileName[sizeof(config.fileName) - 1] = '\0'; - - strncpy(config.logdir, "/tmp/rdk_logger_rotation_test", sizeof(config.logdir) - 1); - config.logdir[sizeof(config.logdir) - 1] = '\0'; - - config.maxSize = 1024; - config.maxCount = 3; - + + strncpy(config.fileLocation, "/tmp/rdk_logger_rotation_test", sizeof(config.fileLocation) - 1); + config.fileLocation[sizeof(config.fileLocation) - 1] = '\0'; + + config.fileSizeMax = 1024; + config.fileCountMax = 3; + rdk_Error ret = rdk_logger_ext_init(&config); ASSERT_EQ(ret, RDK_SUCCESS) << "Extended initialization should succeed"; - + // Test all log levels rdk_logger_msg_printf(RDK_LOG_FATAL, "LOG.RDK.ROTATION", "Fatal message"); rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.ROTATION", "Error message"); @@ -416,7 +478,7 @@ TEST_F(RDKLoggerRotationTest, DifferentLogLevels) { rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.ROTATION", "Info message"); rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.ROTATION", "Debug message"); rdk_logger_msg_printf(RDK_LOG_TRACE, "LOG.RDK.ROTATION", "Trace message"); - + // Should handle all log levels correctly } #endif diff --git a/unittests/test_rdkloggerExtInit.cpp b/unittests/test_rdkloggerExtInit.cpp new file mode 100644 index 0000000..415dca3 --- /dev/null +++ b/unittests/test_rdkloggerExtInit.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include "rdk_logger.h" +#include "rdk_error.h" +#include "log4c.h" +#include "test_utils.h" + +class RdkLoggerExtInit : public ::testing::Test { +protected: + void SetUp() override { + } + void TearDown() override { + } +}; + +TEST_F(RdkLoggerExtInit, CreatesAppenderAndSetsLevel) { + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "gtest_rdkunittest.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; + testPolicy.fileCountMax = 3; + rdk_logger_ext_config_t cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.loglevel = RDK_LOG_TRACE; + cfg.appender = RDKLOG_OUTPUT_FILE; + cfg.layout = RDKLOG_FORMAT_WITH_DATETIME; + cfg.pFilePolicy = &testPolicy; + rdk_Error ret = rdk_logger_ext_init(&cfg); + ASSERT_EQ(ret, RDK_SUCCESS) << "rdk_logger_ext_init failed"; + + + char fullpath[512]; + snprintf(fullpath, sizeof(fullpath), "%s/%s", testPolicy.fileLocation, testPolicy.fileName); + + + log4c_appender_t* app = log4c_appender_get(fullpath); + ASSERT_NE(app, nullptr) << "Appender not created by rdk_logger_ext_init: " << fullpath; + + for (int i = 0; i < 50; i++) + { + RDK_LOG(RDK_LOG_TRACE, "LOG.RDK.RTMESSAGE", "trace-logging\n"); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.RTMESSAGE", "debug-logging\n"); + RDK_LOG(RDK_LOG_WARN, "LOG.RDK.TEST", "warn-logging\n"); + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.TEST", "info-logging\n"); + } + }); +} + + +TEST_F(RdkLoggerExtInit, StdoutAppenderAndLayout) { + RUN_IN_FORK({ + rdk_logger_ext_config_t cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.loglevel = RDK_LOG_DEBUG; + cfg.appender = RDKLOG_OUTPUT_CONSOLE; + cfg.layout = RDKLOG_FORMAT_ONLY_TEXT; + cfg.pFilePolicy = NULL; + cfg.pCategoryName = (char*)"LOG.RDK"; + rdk_Error ret = rdk_logger_ext_init(&cfg); + ASSERT_EQ(ret, RDK_SUCCESS) << "rdk_logger_ext_init failed for Stdout"; + char appender_name[128]; + const char* category_name = cfg.pCategoryName ? cfg.pCategoryName : "LOG.RDK"; + snprintf(appender_name, sizeof(appender_name), "%s.stdout", category_name); + log4c_appender_t* app = log4c_appender_get(appender_name); + ASSERT_NE(app, nullptr) << "Stdout appender not found"; + + for (int i = 0; i < 50; i++) + { + RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.RTMESSAGE", "error-logging\n"); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.RTMESSAGE", "debug-logging\n"); + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.TEST", "info-logging\n"); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.TEST", "debug-logging\n"); + } + }); +} + + +TEST_F(RdkLoggerExtInit, ComcastDatedViaExtInit) { + RUN_IN_FORK({ + rdk_LogOutput_File testPolicy; + strncpy(testPolicy.fileName, "gtest_comcast_unittest.log", sizeof(testPolicy.fileName)-1); + testPolicy.fileName[sizeof(testPolicy.fileName) - 1] = '\0'; + strncpy(testPolicy.fileLocation, "/tmp", sizeof(testPolicy.fileLocation)-1); + testPolicy.fileLocation[sizeof(testPolicy.fileLocation) - 1] = '\0'; + testPolicy.fileSizeMax = 1024; + testPolicy.fileCountMax = 2; + rdk_logger_ext_config_t cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.loglevel = RDK_LOG_ERROR; + cfg.appender = RDKLOG_OUTPUT_FILE; + cfg.layout = RDKLOG_FORMAT_WITH_THREADID; + cfg.pFilePolicy = &testPolicy; + + rdk_Error ret = rdk_logger_ext_init(&cfg); + ASSERT_EQ(ret, RDK_SUCCESS) << "rdk_logger_ext_init failed for Comcast layout"; + + for (int i = 0; i < 50; i++) + { + RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.RTMESSAGE", "error-logging\n"); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.RTMESSAGE", "debug-logging\n"); + RDK_LOG(RDK_LOG_INFO, "LOG.RDK.TEST", "info-logging\n"); + RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.TEST", "debug-logging\n"); + } + }); +} diff --git a/unittests/test_utils.h b/unittests/test_utils.h new file mode 100644 index 0000000..367f4b8 --- /dev/null +++ b/unittests/test_utils.h @@ -0,0 +1,27 @@ +#ifndef TEST_UTILS_H +#define TEST_UTILS_H + +#include +#include +#include +#include "log4c.h" +#include "rdk_logger.h" + +// Macro to run test code in a forked process +#define RUN_IN_FORK(test_body) \ + do { \ + pid_t pid = fork(); \ + ASSERT_NE(pid, -1) << "fork failed"; \ + if (pid == 0) { \ + log4c_init(); \ + test_body; \ + log4c_fini(); \ + exit(0); \ + } else { \ + int status = 0; \ + waitpid(pid, &status, 0); \ + ASSERT_TRUE(WIFEXITED(status)); \ + ASSERT_EQ(WEXITSTATUS(status), 0); \ + } \ + } while (0) +#endif // TEST_UTILS_H From 335e78d639ad88284937048e380f2351f1d80b0c Mon Sep 17 00:00:00 2001 From: Karunakaran A <48997923+karuna2git@users.noreply.github.com> Date: Tue, 6 Jan 2026 15:58:41 -0500 Subject: [PATCH 33/37] RDKEMW-10792 : Added support for syslog, different format and etc (#42) Reason for change: 1. Added support for syslog 2. Added support for systemd_journal 3. Added explicit support for file capture 4. Added different formatting capability 5. Added Dynamic re-configuration of format, output handler Risks:Medium Priority:P1 Signed-off-by: Karunakaran A --- configure.ac | 86 +- include/Makefile.am | 2 +- include/rdk_debug.h | 4 + include/rdk_error.h | 42 - include/rdk_logger.h | 111 ++- include/rdk_logger_types.h | 51 - include/rdk_utils.h | 69 -- log4crc | 37 +- src/Makefile.am | 12 +- src/include/rdk_debug_priv.h | 17 +- src/rdk_debug.c | 55 +- src/rdk_debug_priv.c | 1263 +++++++++++------------- src/rdk_dynamic_logger.c | 58 +- src/rdk_logger_init.c | 103 +- src/rdk_logger_milestone.c | 5 +- src/rdk_logger_util.c | 359 ------- test/Makefile.am | 13 +- test/rdk_dynamic_logger_test.c | 173 ---- test/rdk_logger_debug_test.c | 176 +--- unittests/CMakeLists.txt | 2 - unittests/main.cpp | 2 +- unittests/rdkEnableLogLevel.cpp | 14 +- unittests/rdkIsDbgEnabled.cpp | 685 ------------- unittests/rdkLoggerErrorTest.cpp | 14 +- unittests/rdkLoggerPerformanceTest.cpp | 6 +- unittests/rdkLoggerRotationTest.cpp | 76 +- unittests/rdkLoggerStreamEnvTest.cpp | 105 -- unittests/rdkloggerInit.cpp | 16 +- unittests/rdkloggerMsgRaw1.cpp | 1 + unittests/rdkloggerMsgVsprintf.cpp | 1 + unittests/test_rdkloggerExtInit.cpp | 17 +- utils/Makefile.am | 1 - utils/rdk_logger_onboard_main.c | 7 +- utils/rdklogctrl.c | 31 +- 34 files changed, 923 insertions(+), 2691 deletions(-) delete mode 100644 include/rdk_error.h delete mode 100644 include/rdk_logger_types.h delete mode 100644 include/rdk_utils.h delete mode 100644 src/rdk_logger_util.c delete mode 100644 test/rdk_dynamic_logger_test.c delete mode 100644 unittests/rdkIsDbgEnabled.cpp delete mode 100644 unittests/rdkLoggerStreamEnvTest.cpp diff --git a/configure.ac b/configure.ac index 030e1c5..362cbbf 100644 --- a/configure.ac +++ b/configure.ac @@ -20,17 +20,13 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. -dnl AC_PREREQ([2.69]) -AC_INIT(rdklogger, 2.4.0) +AC_INIT(rdklogger, [2.4.0]) AC_CONFIG_SRCDIR([src]) -AM_CONFIG_HEADER(cfg/config.h) +AC_CONFIG_HEADERS(config.h) AC_CONFIG_MACRO_DIR([cfg]) AC_CONFIG_AUX_DIR([cfg]) AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-bzip2 1.9]) LT_INIT -IS_DYNAMIC_ENABLED="" -IS_MILESTONE_ENABLED="" -IS_ONBOARDLOG_ENABLED="" dnl subdirectories. @@ -53,70 +49,26 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])], dnl ********************************** dnl checks for dependencies dnl ********************************** -SYSLOG_HELPER_CFLAGS=" " -SYSLOG_HELPER_LDFLAGS=" " - -AC_ARG_ENABLE([systemd-syslog-helper], - AS_HELP_STRING([--enable-systemd-syslog-helper],[enable systemd syslog logging]), - [ - case "${enableval}" in - yes) SYSLOG_HELPER_CFLAGS="-DSYSTEMD_SYSLOG_HELPER" - SYSLOG_HELPER_LDFLAGS="-lsysloghelper" ;; - no) AC_MSG_ERROR([systemd syslog logging is disabled]) ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-systemd-syslog-helper ]) ;; - esac - ], - [echo "systemd syslog logging is disable"]) - -AC_SUBST(SYSLOG_HELPER_CFLAGS) -AC_SUBST(SYSLOG_HELPER_LDFLAGS) - -SYSTEMD_CFLAGS=" " -SYSTEMD_LDFLAGS=" " -AC_ARG_ENABLE([journal], - AS_HELP_STRING([--enable-journal],[enable systemd journal logging]), - [ - case "${enableval}" in - yes) SYSTEMD_CFLAGS="-DSYSTEMD_JOURNAL" - SYSTEMD_LDFLAGS="-lsystemd" ;; - no) AC_MSG_ERROR([systemd journal logging is disabled]) ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-journal ]) ;; - esac - ], - [echo "journal logging is disable"]) - -AC_SUBST(SYSTEMD_CFLAGS) -AC_SUBST(SYSTEMD_LDFLAGS) - -AC_ARG_ENABLE([milestone], - AS_HELP_STRING([--enable-milestone],[enable milestone (default is no)]), - [ - case "${enableval}" in - yes) IS_MILESTONE_ENABLED=true ;; - no) IS_MILESTONE_ENABLED=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-milestone]) ;; - esac - ], - [echo "Milestone support is disabled"]) -AM_CONDITIONAL([IS_MILESTONE_ENABLED], [test x$IS_MILESTONE_ENABLED = xtrue]) - -AC_ARG_ENABLE([onboardlog], - AS_HELP_STRING([--enable-onboardlog],[enable onboardlog (default is no)]), - [ - case "${enableval}" in - yes) IS_ONBOARDLOG_ENABLED=true ;; - no) IS_ONBOARDLOG_ENABLED=false ;; - *) AC_MSG_ERROR([bad value ${enableval} for --enable-onboardlog]) ;; - esac - ], - [echo "Milestone support is disabled"]) -AM_CONDITIONAL([IS_ONBOARDLOG_ENABLED], [test x$IS_ONBOARDLOG_ENABLED = xtrue]) - -AC_HEADER_STDC +# Optional check: only use systemd if it is found +PKG_CHECK_MODULES([SYSTEMD], [libsystemd >= 209], [ + AC_DEFINE([HAVE_SYSTEMD], [1], [Define if libsystemd is available]) + # The header is part of libsystemd, but we can verify it explicitly + AC_CHECK_HEADERS([systemd/sd-journal.h]) +], [ + AC_MSG_WARN([libsystemd not found; systemd support will be disabled]) +]) + +# Substitute variables for Makefile.am +AC_SUBST([SYSTEMD_CFLAGS]) +AC_SUBST([SYSTEMD_LIBS]) dnl Checks for header files. AC_CHECK_HEADERS([limits.h memory.h stdlib.h string.h sys/socket.h unistd.h]) +dnl Checks for syslog header file & functions. +AC_CHECK_HEADERS([syslog.h]) +AC_CHECK_FUNCS([openlog syslog closelog]) + dnl Checks for typedefs, structures, and compiler characteristics. dnl AC_CHECK_HEADER_STDBOOL AC_TYPE_UINT8_T @@ -128,7 +80,7 @@ AC_CHECK_FUNCS([memset strdup strerror]) PKG_CHECK_MODULES([LOG4C], [log4c >= 1.2.3]) AC_CONFIG_FILES([Makefile - cfg/Makefile + cfg/Makefile src/Makefile test/Makefile utils/Makefile diff --git a/include/Makefile.am b/include/Makefile.am index 340af64..e9c8b9c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -19,4 +19,4 @@ SUBDIRS = librdkloggers_la_includedir = $(includedir) -librdkloggers_la_include_HEADERS = rdk_logger.h rdk_debug.h rdk_error.h rdk_logger_types.h rdk_logger_milestone.h +librdkloggers_la_include_HEADERS = rdk_logger.h rdk_debug.h rdk_logger_milestone.h diff --git a/include/rdk_debug.h b/include/rdk_debug.h index ade3708..818aad8 100644 --- a/include/rdk_debug.h +++ b/include/rdk_debug.h @@ -27,4 +27,8 @@ #include "rdk_logger.h" +/* For legacy projects that does not include essential headers but relying on rdk_debug.h */ +#include +#include + #endif /* _RDK_DEBUG_H_ */ diff --git a/include/rdk_error.h b/include/rdk_error.h deleted file mode 100644 index 991f091..0000000 --- a/include/rdk_error.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * If not stated otherwise in this file or this component's LICENSE file the - * following copyright and licenses apply: - * - * Copyright 2016 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#if !defined(_RDK_ERROR_H_) -#define _RDK_ERROR_H_ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#ifndef uint32_t -typedef unsigned int uint32_t; -#endif - -#define RDK_SUCCESS 0 -#define RDK_FAILURE -1 -typedef int32_t rdk_Error; - - -#ifdef __cplusplus -} -#endif - -#endif /* _RDK_ERROR_H_ */ - diff --git a/include/rdk_logger.h b/include/rdk_logger.h index 59ad121..91fb314 100644 --- a/include/rdk_logger.h +++ b/include/rdk_logger.h @@ -111,18 +111,37 @@ #define _RDK_LOGGER_H_ #include -#include "rdk_logger_types.h" -#include "rdk_error.h" +#include +#include +#include +#include + #ifdef __cplusplus extern "C" { #endif +typedef int32_t rdk_Error; +typedef bool rdk_logger_Bool; /** * Macros for ease of applications using RDK_LOGGER apis */ +/** + * Define the return code for logger API + */ +#define RDK_SUCCESS 0 +#define RDK_FAILURE -1 + +#ifndef TRUE +#define TRUE (1==1) +#endif + +#ifndef FALSE +#define FALSE (1!=1) +#endif + /** * Define the default location of configuration file location */ @@ -131,16 +150,18 @@ extern "C" /** * Support for overriding debug.ini file location */ -#ifndef DEBUG_INI_OVERRIDE_PATH -#define DEBUG_INI_OVERRIDE_PATH "/nvram/debug.ini" -#endif +#define DEBUG_INI_OVERRIDE_PATH_1 "/opt/debug.ini" +#define DEBUG_INI_OVERRIDE_PATH_2 "/nvram/debug.ini" /** * Support for Init function */ -#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH, F_OK)) \ - ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH) \ - : rdk_logger_init(DEBUG_INI_NAME); +#define RDK_LOGGER_INIT() (0 == access(DEBUG_INI_OVERRIDE_PATH_1, F_OK)) \ + ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH_1) \ + : (0 == access(DEBUG_INI_OVERRIDE_PATH_2, F_OK)) \ + ? rdk_logger_init(DEBUG_INI_OVERRIDE_PATH_2) \ + : rdk_logger_init(DEBUG_INI_NAME); + /** * Use RDK_LOG debug message as. * RDK_LOG (rdk_LogLevel level, const char *module, const char *format,...) @@ -150,15 +171,16 @@ extern "C" */ #define RDK_LOG rdk_logger_msg_printf #define RDK_LOG1 rdk_logger_msg_vsprintf + /** * Define the max length for the log file capture */ -#define RDK_LOGGER_EXT_FILENAME_SIZE 64 +#define RDKLOG_MAX_FILENAME_SIZE 64 /** * Define the max length for the log capture path */ -#define RDK_LOGGER_EXT_LOGDIR_SIZE 256 +#define RDKLOG_MAX_PATH_SIZE 256 /** * To allow compatibility of mutiple legacy RDK components using loglevels RDK_LOG_TRACE1..RDK_LOG_TRACE9 @@ -201,36 +223,39 @@ typedef enum } rdk_LogLevel; /** - * @enum rdk_LogOutput - * @brief Defines the destination type where log events are written. + * @enum rdk_LogFormat + * @brief Defines the layout/format used to render log messages. * - * - RDKLOG_OUTPUT_CONSOLE: Write logs to the process stdout/stderr stream (typically mapped via stream_env). - * - RDKLOG_OUTPUT_FILE: Write logs to rolling files on disk (uses rollingfile appender). - * - RDKLOG_OUTPUT_SYSLOG: Forward logs to the local syslog daemon. + * - RDKLOG_FORMAT_PLAINTEXT: Simple layout (priority, category, message). + * - RDKLOG_FORMAT_WITH_TS: Timestamped layout including date/time and milliseconds. + * - RDKLOG_FORMAT_DETAIL_WITH_TS: Specific layout with the exact fields + * (such as module, level, thread id) with time stamped + * - RDKLOG_FORMAT_DETAIL_WITHOUT_TS: Same as above but without timestamp */ typedef enum { - RDKLOG_OUTPUT_CONSOLE = 0, - RDKLOG_OUTPUT_SYSLOG, - RDKLOG_OUTPUT_FILE -} rdk_LogOutput; + RDKLOG_FORMAT_PLAINTEXT = 0, /** format_plaintext */ + RDKLOG_FORMAT_WITH_TS, /** format_with_ts */ + RDKLOG_FORMAT_DETAIL_WITH_TS, /** format_detail_with_ts */ + RDKLOG_FORMAT_DETAIL_WITHOUT_TS /** format_detail_without_ts */ +} rdk_LogFormat; /** - * @enum rdk_LogFormat - * @brief Defines the layout/format used to render log messages. + * @enum rdk_LogOutput + * @brief Defines the destination type where log events are written. * - * - RDKLOG_FORMAT_ONLY_TEXT: Simple layout (priority, category, message). - * - RDKLOG_FORMAT_WITH_DATETIME: Timestamped layout including date/time and milliseconds. - * - RDKLOG_FORMAT_WITH_THREADID: Comcast-specific dated layout with the exact fields - * (such as module, level, thread id, etc.) - * depend on the configured layout implementation. + * - RDKLOG_OUTPUT_CONSOLE: Write logs to the process stdout/stderr stream (typically mapped via stream_env). + * - RDKLOG_OUTPUT_FILE: Write logs to rolling files on disk (uses rollingfile appender). + * - RDKLOG_OUTPUT_JOURNAL: Write logs to systemd journal + * - RDKLOG_OUTPUT_SYSLOG: Write logs to the local syslog daemon. */ typedef enum { - RDKLOG_FORMAT_ONLY_TEXT = 0, - RDKLOG_FORMAT_WITH_DATETIME, - RDKLOG_FORMAT_WITH_THREADID -} rdk_LogFormat; + RDKLOG_OUTPUT_CONSOLE = 0, /** to_console */ + RDKLOG_OUTPUT_SYSLOG, /** to_syslog */ + RDKLOG_OUTPUT_JOURNAL, /** to_journal */ + RDKLOG_OUTPUT_FILE /** to_file */ +} rdk_LogOutput; /** * @brief rdk_LogOutput_File structure for rolling file appenders. @@ -240,11 +265,12 @@ typedef enum */ typedef struct rdk_LogOutput_File { - char fileName[RDK_LOGGER_EXT_FILENAME_SIZE]; - char fileLocation[RDK_LOGGER_EXT_LOGDIR_SIZE]; - int8_t fileCountMax; + char fileName[RDKLOG_MAX_FILENAME_SIZE]; + char fileLocation[RDKLOG_MAX_PATH_SIZE]; + int8_t fileCountMax; int64_t fileSizeMax; } rdk_LogOutput_File; + /** * @brief Complete logger configuration structure for structured initialization. * @@ -253,10 +279,10 @@ typedef struct rdk_LogOutput_File */ typedef struct rdk_logger_ext_config_t { - char* pCategoryName; /**< Log category name (e.g., "LOG.RDK.TR69") */ + char* pModuleName; /**< Log module name (e.g., "LOG.RDK.TR69") */ rdk_LogLevel loglevel; /**< Default log level for this category */ - rdk_LogOutput appender; /**< Type of appender */ - rdk_LogFormat layout; /**< Message layout format */ + rdk_LogOutput output; /**< Type of output/appender */ + rdk_LogFormat format; /**< Type of log format */ rdk_LogOutput_File *pFilePolicy; /**< File policy configuration (required for RDKLOG_OUTPUT_FILE, NULL for others) */ } rdk_logger_ext_config_t; @@ -303,7 +329,7 @@ void rdk_logger_msg_vsprintf(rdk_LogLevel level, const char *module, const char * @param level Log level. * @return TRUE if enabled, FALSE otherwise. */ -rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); +bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level); /** * @brief Enable or disable a log level for a module. @@ -312,7 +338,7 @@ rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel * @param enableLogLvl TRUE to enable, FALSE to disable. * @return TRUE if successful, FALSE otherwise. */ -rdk_logger_Bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); +bool rdk_logger_set_logLevel(const char *module, rdk_LogLevel logLevel); /** * @brief Log a message for onboard logging. @@ -338,6 +364,15 @@ void rdk_dbg_MsgRaw(rdk_LogLevel level, const char *module, const char *format, */ void rdk_dbg_MsgRaw1(rdk_LogLevel level, const char *module, const char *format, va_list args); +/** + * @brief Enable or disable a log level for a module. + * @param module Module name. + * @param logLevel Log level. + * @param enableLogLvl TRUE to enable, FALSE to disable. + * @return TRUE if successful, FALSE otherwise. + */ +bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl); + /** * @brief Convert a log level string to rdk_LogLevel enum. * @param level Log level as string (e.g., "INFO", "DEBUG"). diff --git a/include/rdk_logger_types.h b/include/rdk_logger_types.h deleted file mode 100644 index 6e389ed..0000000 --- a/include/rdk_logger_types.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * If not stated otherwise in this file or this component's LICENSE file the - * following copyright and licenses apply: - * - * Copyright 2016 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#if !defined(_RDK_LOGGER_TYPES_H_) -#define _RDK_LOGGER_TYPES_H_ - -#ifndef __ASSEMBLY__ - -#include -#include -#include -#include /* uint32_t etc. */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef int32_t rdk_logger_Bool; - -#ifndef TRUE -#define TRUE (1==1) -#endif - -#ifndef FALSE -#define FALSE (1!=1) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _RDK_LOGGER_TYPES_H_ */ - -#endif /*__ASSEMBLY__*/ /*FD-20090114*/ diff --git a/include/rdk_utils.h b/include/rdk_utils.h deleted file mode 100644 index ee19f25..0000000 --- a/include/rdk_utils.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * If not stated otherwise in this file or this component's LICENSE file the - * following copyright and licenses apply: - * - * Copyright 2016 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -/** - * @file rdk_utils.h - * The header file provides RDK Utils APIs. - */ - - -/** -* @defgroup rdk_logger -* @{ -* @defgroup include -* @{ -**/ - - -#ifndef _RDK_UTILS_H_ -#define _RDK_UTILS_H_ - -#include -#include -#ifdef __cplusplus -extern "C" -{ -#endif - -/** - * @ingroup RDKLOGGER_UTILS_API - * @{ - */ - -const char* rdk_logger_envGet(const char *name); - -int rdk_logger_envGetNum(const char * mod); - -const char* rdk_logger_envGetValueFromNum(int number); - -const char* rdk_logger_envGetModFromNum(int Num); - -rdk_Error rdk_logger_parse_config(const char * path); - -rdk_Error rdk_logger_release_config(void); - -char* rdk_loglevelToString(rdk_LogLevel level, rdk_logger_Bool isLogEnabled); -/** @} */ //end of Doxygen tag RDKLOGGER_UTILS_API - -#ifdef __cplusplus -} -#endif - -#endif /* _RDK_DEBUG_H_ */ - diff --git a/log4crc b/log4crc index 67f35fe..f3df546 100644 --- a/log4crc +++ b/log4crc @@ -1,39 +1,20 @@ - - 0 - + 1024 - 0 - 0 - - - - - - - - - - + + + + - + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 683a31c..6ca2fd2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,10 +17,10 @@ # limitations under the License. ########################################################################## -AM_CPPFLAGS = -pthread -Wall +AM_CFLAGS = -pthread -Wall -Werror lib_LTLIBRARIES = librdkloggers.la -librdkloggers_la_SOURCES = rdk_debug.c rdk_debug_priv.c rdk_dynamic_logger.c rdk_logger_init.c rdk_logger_util.c rdk_logger_milestone.c -librdkloggers_la_SOURCES += rdk_logger_onboard.c -librdkloggers_la_CFLAGS = $(LOG4C_CFLAGS) $(GLIB_CFLAGS) $(SYSLOG_HELPER_CFLAGS) $(SYSTEMD_CLFAGS) -I./include -I../include -I${RDK_PROJECT_ROOT_PATH}/opensource/include/log4c -I${RDK_PROJECT_ROOT_PATH}/opensource/include -DDEBUG_CONF_FILE="\"debug.ini\"" -librdkloggers_la_LDFLAGS = $(GLIB_LIBS) $(LOG4C_LIBS) $(SYSLOG_HELPER_LDFLAGS) $(SYSTEMD_LDFLAGS) -librdkloggers_la_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/include -I$(top_srcdir)/include +librdkloggers_la_SOURCES = rdk_debug.c rdk_debug_priv.c rdk_dynamic_logger.c rdk_logger_init.c rdk_logger_milestone.c rdk_logger_onboard.c +librdkloggers_la_CFLAGS = $(LOG4C_CFLAGS) $(GLIB_CFLAGS) $(SYSTEMD_CFLAGS) -I$(top_srcdir)/include -I$(top_srcdir)/src/include -DDEBUG_CONF_FILE="\"debug.ini\"" +librdkloggers_la_LDFLAGS = $(GLIB_LIBS) $(LOG4C_LIBS) $(SYSTEMD_LIBS) + + diff --git a/src/include/rdk_debug_priv.h b/src/include/rdk_debug_priv.h index d20e5f4..532ff83 100644 --- a/src/include/rdk_debug_priv.h +++ b/src/include/rdk_debug_priv.h @@ -20,27 +20,18 @@ #if !defined(_RDK_DBG_PRIV_H) #define _RDK_DBG_PRIV_H -#include #include -#include -#include -#include - #ifdef __cplusplus extern "C" { #endif void rdk_dbg_priv_init(void); -void rdk_dbg_priv_config(void); -rdk_Error rdk_dbg_priv_ext_init(const rdk_logger_ext_config_t* config); -void rdk_dbg_priv_shutdown(); - +rdk_Error rdk_dbg_priv_config(const char *pConfigFile); +void rdk_dbg_priv_deinit(void); +rdk_Error rdk_dbg_priv_ext_init (const rdk_logger_ext_config_t* config); void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args); -void rdk_dbg_priv_reconfig(const char *pModuleName, const char *pLogLevel); - -void rdk_dbg_init(); -void rdk_dbg_deinit(); +bool rdk_dbg_priv_log_reconfig(const char *pModuleName, rdk_LogLevel level); #ifdef __cplusplus } diff --git a/src/rdk_debug.c b/src/rdk_debug.c index b4903f0..fbfba61 100644 --- a/src/rdk_debug.c +++ b/src/rdk_debug.c @@ -29,38 +29,11 @@ * @{ **/ - #include #include - -#include // memset -#include +#include #include -/** - * @brief Initialize the underlying MPEOS debug support. This API must be called only once per boot cycle. - * @return None. - */ -static rdk_logger_Bool inited = FALSE; -void rdk_dbg_init() -{ - - if (!inited) - { - rdk_dbg_priv_init(); - inited = TRUE; - rdk_dbg_priv_config(); - } -} - -void rdk_dbg_deinit() -{ - if (inited) - { - inited = FALSE; - } -} - /** * @brief Send a debugging message to the debugging window. It is appended to the log output based * on configurations set in the environment file. @@ -111,20 +84,24 @@ void rdk_dbg_MsgRaw1(rdk_LogLevel level, const char *module, const char *format, * @param[in] module The module name or category for for which the log level shall be checked * @param[in] level The debug logging level. * - * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. + * @return Returns true, if debug log level enabled successfully else returns false. */ -rdk_logger_Bool rdk_logger_enable_logLevel(const char *pModuleName, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl) +bool rdk_logger_set_logLevel(const char *module, rdk_LogLevel logLevel) { - if (!pModuleName) - return FALSE; - - const char* logLevelName = rdk_loglevelToString(logLevel, enableLogLvl); - - if (!logLevelName) - return FALSE; + return rdk_dbg_priv_log_reconfig(module, logLevel); +} - rdk_dbg_priv_reconfig (pModuleName, logLevelName); - return TRUE; +/** + * @brief Enable or disable a log level for a module. + * @param module Module name. + * @param logLevel Log level. + * @param enableLogLvl TRUE to enable, FALSE to disable. + * @return TRUE if successful, FALSE otherwise. + */ +bool rdk_logger_enable_logLevel(const char *module, rdk_LogLevel logLevel, rdk_logger_Bool enableLogLvl) +{ + (void) enableLogLvl; + return rdk_dbg_priv_log_reconfig(module, logLevel); } /** diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index ec2ece7..0eebe7e 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -29,10 +29,10 @@ * @{ **/ - +#include #include #include -/*lint -e(451)*/ +#include #include #include #include @@ -46,438 +46,497 @@ #include #include - -#include "rdk_logger_types.h" -#include "rdk_error.h" -#define RDK_DEBUG_DEFINE_STRINGS #include "rdk_debug_priv.h" #include "rdk_dynamic_logger.h" #include "log4c.h" -#include #include #include #include -#ifdef SYSTEMD_JOURNAL +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_SYSTEMD #include -#endif //SYSTEMD_JOURNAL +#endif //HAVE_SYSTEMD +#ifdef HAVE_SYSLOG_H +#include +#endif //HAVE_SYSLOG_H -#ifdef SYSTEMD_SYSLOG_HELPER -#include "syslog_helper_ifc.h" -#endif log4c_category_t* gRootCat = NULL; -int gRootPriority = 0; -extern int global_count; - -static int rdk_logLevel_to_log4c_priority(int level) { - switch (level) { - case 0: return LOG4C_PRIORITY_FATAL; // 000 - case 1: return LOG4C_PRIORITY_ERROR; // 300 - case 2: return LOG4C_PRIORITY_WARN; // 400 - case 3: return LOG4C_PRIORITY_NOTICE; // 500 - case 4: return LOG4C_PRIORITY_INFO; // 600 - case 5: return LOG4C_PRIORITY_DEBUG; // 700 - case 6: return LOG4C_PRIORITY_TRACE; // 800 - default: return LOG4C_PRIORITY_UNKNOWN; - } - } +int gRootPriority = LOG4C_PRIORITY_WARN; +const char* gRootCatName = "LOG.RDK"; +static pthread_mutex_t gLoggingMutex = PTHREAD_MUTEX_INITIALIZER; + +/* 1024 is allowed; but lets leave some space for timestamp */ +#define LOG4C_MSG_BUFFER_SIZE 980 -#define LOG4C_PRIORITY_NONE -1 +/* Define the priority as -ve to avoid printing */ +#define LOG4C_PRIORITY_NONE -1 /** - * Returns 1 if logging has been requested for the corresponding module (mod) - * and level (lvl) combination. To be used in rdk_dbg_priv_* files ONLY. + * Declare format/layout APIs. */ -#define IS_LOGGING_ENABLED_FOR_LEVEL(module_name, level) \ - (log4c_category_get(module_name) && \ - (rdk_logLevel_to_log4c_priority(level) <= log4c_category_get_priority(log4c_category_get(module_name)))) - -/** Skip whitespace in a c-style string. */ -#define SKIPWHITE(cptr) while ((*cptr != '\0') && isspace(*cptr)) cptr++ - -#define HOSTADDR_STR_MAX 255 - - -#define MAX_LOGLINE_LENGTH 4096 - -static int initLogger(char *category); - -static const char* dated_format_nocr(const log4c_layout_t* a_layout, - const log4c_logging_event_t*a_event); -static const char* basic_format_nocr(const log4c_layout_t* a_layout, - const log4c_logging_event_t*a_event); -static const char* comcast_dated_format_nocr(const log4c_layout_t* a_layout, - log4c_logging_event_t*a_event); -static int stream_env_overwrite_open(log4c_appender_t * appender); -static int stream_env_append_open(log4c_appender_t * appender); -static int stream_env_append(log4c_appender_t* appender, const log4c_logging_event_t* event); -static int stream_env_plus_stdout_append(log4c_appender_t* appender, const log4c_logging_event_t* event); -static int stream_env_close(log4c_appender_t * appender); +static const char* rdk_plaintext(const log4c_layout_t* a_layout, const log4c_logging_event_t* a_event); +static const char* rdk_with_ts(const log4c_layout_t* a_layout, const log4c_logging_event_t* a_event); +static const char* rdk_detail_with_ts(const log4c_layout_t* a_layout, const log4c_logging_event_t* a_event); +static const char* rdk_detail_without_ts(const log4c_layout_t* a_layout, const log4c_logging_event_t* a_event); +static const char* rdk_detail_format_handler(const log4c_layout_t* layout, const log4c_logging_event_t* event, bool isTimed); /** - * Initialize Debug API. + * Initialize Layout API. */ -static const log4c_layout_type_t log4c_layout_type_dated_nocr = -{ "dated_nocr", dated_format_nocr, }; - -static const log4c_layout_type_t log4c_layout_type_basic_nocr = -{ "basic_nocr", basic_format_nocr, }; +static const log4c_layout_type_t log4c_layout_type_rdk_plaintext = {"format_plaintext", rdk_plaintext}; +static const log4c_layout_type_t log4c_layout_type_rdk_with_ts = {"format_with_ts", rdk_with_ts}; +static const log4c_layout_type_t log4c_layout_type_rdk_detail_with_ts = {"format_detail_with_ts", rdk_detail_with_ts}; +static const log4c_layout_type_t log4c_layout_type_rdk_detail_without_ts = {"format_detail_without_ts", rdk_detail_without_ts}; -static const log4c_layout_type_t log4c_layout_type_comcast_dated_nocr = -{ "comcast_dated_nocr", comcast_dated_format_nocr, }; - -static const log4c_appender_type_t - log4c_appender_type_stream_env = - { "stream_env", stream_env_overwrite_open, stream_env_append, - stream_env_close, }; +/** + * Initialize Appender API. + */ +static int to_console_open(log4c_appender_t * appender); +static int to_console_append(log4c_appender_t* appender, const log4c_logging_event_t* event); +static int to_console_close(log4c_appender_t * appender); + +static int to_syslog_open(log4c_appender_t * appender); +static int to_syslog_append(log4c_appender_t* appender, const log4c_logging_event_t* event); +static int to_syslog_close(log4c_appender_t * appender); + +static int to_journal_open(log4c_appender_t * appender); +static int to_journal_append(log4c_appender_t* appender, const log4c_logging_event_t* event); +static int to_journal_close(log4c_appender_t * appender); + +static const log4c_appender_type_t log4c_appender_type_to_console = {"to_console", + to_console_open, + to_console_append, + to_console_close + }; + +static const log4c_appender_type_t log4c_appender_type_to_syslog = {"to_syslog", + to_syslog_open, + to_syslog_append, + to_syslog_close + }; + +static const log4c_appender_type_t log4c_appender_type_to_journal = {"to_journal", + to_journal_open, + to_journal_append, + to_journal_close + }; + +static int rdk_logLevel_to_log4c_priority(rdk_LogLevel level) +{ + switch (level) + { + case RDK_LOG_FATAL: return LOG4C_PRIORITY_FATAL; // 000 + case RDK_LOG_ERROR: return LOG4C_PRIORITY_ERROR; // 300 + case RDK_LOG_WARN: return LOG4C_PRIORITY_WARN; // 400 + case RDK_LOG_NOTICE: return LOG4C_PRIORITY_NOTICE; // 500 + case RDK_LOG_INFO: return LOG4C_PRIORITY_INFO; // 600 + case RDK_LOG_DEBUG: return LOG4C_PRIORITY_DEBUG; // 700 + case RDK_LOG_TRACE: return LOG4C_PRIORITY_TRACE; // 800 + case RDK_LOG_NONE: return LOG4C_PRIORITY_UNKNOWN; // 1000 + } + return LOG4C_PRIORITY_UNKNOWN; +} -static const log4c_appender_type_t log4c_appender_type_stream_env_append = -{ "stream_env_append", stream_env_append_open, stream_env_append, - stream_env_close, }; +#if defined(HAVE_SYSTEMD) || defined(HAVE_SYSLOG_H) +static int get_syslog_priority(int log4c_pr) +{ + int priority; + switch(log4c_pr) + { + case LOG4C_PRIORITY_FATAL: + priority = LOG_EMERG; + break; + case LOG4C_PRIORITY_ERROR: + priority = LOG_ERR; + break; + case LOG4C_PRIORITY_WARN: + priority = LOG_WARNING; + break; + case LOG4C_PRIORITY_NOTICE: + priority = LOG_NOTICE; + break; + case LOG4C_PRIORITY_INFO: + priority = LOG_INFO; + break; + case LOG4C_PRIORITY_DEBUG: + case LOG4C_PRIORITY_TRACE: + default: + priority = LOG_DEBUG; + break; + } + return priority; +} +#endif /* HAVE_SYSTEMD */ -static const log4c_appender_type_t log4c_appender_type_stream_env_plus_stdout = -{ "stream_env_plus_stdout", stream_env_overwrite_open, - stream_env_plus_stdout_append, stream_env_close, }; +static void trim(char *instr, char* outstr) +{ + char *ptr = instr; + char *endptr = instr + strlen(instr)-1; + int length; -static const log4c_appender_type_t log4c_appender_type_stream_env_append_plus_stdout = -{ "stream_env_append_plus_stdout", stream_env_append_open, - stream_env_plus_stdout_append, stream_env_close, }; + /* Advance pointer to first non-whitespace char */ + while (isspace(*ptr)) + ptr++; -void rdk_dbg_priv_init() -{ - if (initLogger("LOG.RDK")) + if (ptr > endptr) { - fprintf(stderr, "%s -- initLogger failure?!\n", __FUNCTION__); + /* + * avoid breaking things when there are + * no non-space characters in instr (JIRA OCORI-2028) + */ + outstr[0] = '\0'; + return; } - gRootCat = log4c_category_get("LOG.RDK"); + /* Move end pointer toward the front to first non-whitespace char */ + while (isspace(*endptr)) + endptr--; + + length = endptr + 1 - ptr; + strncpy(outstr,ptr,length); + outstr[length] = '\0'; + } -static log4c_appender_t* rdk_dbg_priv_appender_init(const char* categoryName, rdk_LogOutput app, - rdk_LogFormat layout, rdk_LogOutput_File *pPolicy) +rdk_Error rdk_logger_parse_config( const char * path) { - char app_name[256]; + FILE* f = NULL; + const int line_buf_len = 256; + char lineBuffer[line_buf_len]; - if (!categoryName) + if (!path) { - fprintf(stderr, "Error: categoryName is NULL\n"); - return NULL; + printf("Invalid config file\n"); + return RDK_FAILURE; } - if (app == RDKLOG_OUTPUT_FILE && pPolicy) - { - snprintf(app_name, sizeof(app_name), "%s.app", categoryName); - } - else - { - snprintf(app_name, sizeof(app_name), "%s.stdout", categoryName); - } - log4c_appender_t* appender = log4c_appender_get(app_name); - if (appender) + /* Open the env file */ + if ((f = fopen( path,"r")) == NULL) { - (void)log4c_appender_close(appender); - (void)log4c_appender_set_udata(appender, NULL); - } - else - { - appender = log4c_appender_new(app_name); - if (!appender) - { - fprintf(stderr, "Failed to create appender %s\n", app_name); - return NULL; - } + printf("** ERROR! Could not open configuration file (%s)! **\n", path); + return RDK_FAILURE; } - const char* type_str = NULL; - switch (app) + memset(lineBuffer, 0, line_buf_len); + /* Read each line of the file */ + while (fgets(lineBuffer, line_buf_len, f) != NULL) { - case RDKLOG_OUTPUT_CONSOLE: type_str = "stream_env"; break; - case RDKLOG_OUTPUT_FILE: type_str = "rollingfile"; break; - case RDKLOG_OUTPUT_SYSLOG: type_str = "syslog"; break; - default: type_str = "stream_env"; break; - } + char name[line_buf_len]; + char value[line_buf_len]; + char trimname[line_buf_len]; + char trimvalue[line_buf_len]; + char *equals; + int length; - const log4c_appender_type_t* type = log4c_appender_type_get(type_str); - if (type) - { - log4c_appender_set_type(appender, type); - } + /* Ignore comment lines */ + if (lineBuffer[0] == '#') + continue; - if (app == RDKLOG_OUTPUT_FILE && pPolicy) - { - rollingfile_udata_t *rudata = rollingfile_make_udata(); - if (rudata && pPolicy->fileLocation && pPolicy->fileName) + /* Ignore lines that do not have an '=' char */ + if ((equals = strchr(lineBuffer,'=')) == NULL) + continue; + + /* Read the property and store in the cache */ + length = equals - lineBuffer; + strncpy(name, lineBuffer,length); + name[length] = '\0'; /* have to null-term */ + + length = lineBuffer + strlen(lineBuffer) - equals + 1; + strncpy(value, equals+1, length); + value[length] = '\0' ; + + /* Trim all whitespace from name and value strings */ + trim(name, trimname); + trim(value, trimvalue); + +#define COMP_SIGNATURE "LOG.RDK." +#define COMP_SIGNATURE_LEN 8 + if (strcmp("LOG.RDK.DEFAULT", trimname) == 0) { - rollingfile_udata_set_logdir(rudata, pPolicy->fileLocation); - rollingfile_udata_set_files_prefix(rudata, pPolicy->fileName); - long maxBytes = (pPolicy->fileSizeMax > 0) ? pPolicy->fileSizeMax : 1024 * 1024; + if (!gRootCat) + gRootCat = log4c_category_get("LOG.RDK"); - char policy_name[256]; - snprintf(policy_name, sizeof(policy_name), "policy_%s", log4c_appender_get_name(appender)); - if (pPolicy->fileCountMax > 0) + if (gRootCat) { - log4c_rollingpolicy_t *policy = log4c_rollingpolicy_get(policy_name); - if (!policy) + if (strcasecmp(trimvalue, "NONE") == 0) { - policy = log4c_rollingpolicy_new(policy_name); + log4c_category_set_priority(gRootCat, LOG4C_PRIORITY_NONE); } - - if (policy) + else { - const log4c_rollingpolicy_type_t* rtype = log4c_rollingpolicy_type_get("sizewin"); - if (rtype) + int lvl = rdk_logger_level_from_string(trimvalue); + if ((lvl >= RDK_LOG_FATAL) && (lvl < RDK_LOG_NONE)) { - log4c_rollingpolicy_set_type(policy, rtype); + log4c_category_set_priority(gRootCat, rdk_logLevel_to_log4c_priority(lvl)); } - - rollingpolicy_sizewin_udata_t *sizewin_udata = sizewin_make_udata(); - if (sizewin_udata) - { - sizewin_udata_set_file_maxsize(sizewin_udata, maxBytes); - sizewin_udata_set_max_num_files(sizewin_udata, pPolicy->fileCountMax); - log4c_rollingpolicy_set_udata(policy, sizewin_udata); - } - rollingfile_udata_set_policy(rudata, policy); } + gRootPriority = log4c_category_get_priority(gRootCat); } - log4c_appender_set_udata(appender, rudata); } - else + else if (strncmp(COMP_SIGNATURE, trimname, COMP_SIGNATURE_LEN) == 0) { - fprintf(stderr, "ruData or logdir or fileName is NULL\n"); - return NULL; + log4c_category_t* cat = log4c_category_get(trimname); + if (cat) + { + if (strcasecmp(trimvalue, "NONE") == 0) + { + log4c_category_set_priority(cat, LOG4C_PRIORITY_NONE); + } + else + { + int lvl = rdk_logger_level_from_string(trimvalue); + if ((lvl >= RDK_LOG_FATAL) && (lvl < RDK_LOG_NONE)) + { + log4c_category_set_priority(cat, rdk_logLevel_to_log4c_priority(lvl)); + } + else + { + log4c_category_set_priority(cat, LOG4C_PRIORITY_NONE); + } + } + } } } - const char* layout_str = NULL; - switch (layout) - { - case RDKLOG_FORMAT_ONLY_TEXT: layout_str = "basic"; break; - case RDKLOG_FORMAT_WITH_DATETIME: layout_str = "dated"; break; - case RDKLOG_FORMAT_WITH_THREADID: layout_str = "comcast_dated"; break; - default: layout_str = "basic"; break; - } + fclose( f); + return RDK_SUCCESS; +} - log4c_layout_t* layout_obj = log4c_layout_get(layout_str); - if (layout_obj) - { - log4c_appender_set_layout(appender, layout_obj); - } +void rdk_dbg_priv_init(void) +{ + ///> These must be set before calling log4c_init so that the log4crc file + ///> will configure them + (void) log4c_layout_type_set(&log4c_layout_type_rdk_plaintext); + (void) log4c_layout_type_set(&log4c_layout_type_rdk_with_ts); + (void) log4c_layout_type_set(&log4c_layout_type_rdk_detail_with_ts); + (void) log4c_layout_type_set(&log4c_layout_type_rdk_detail_without_ts); - if (log4c_appender_open(appender) != 0) - { - fprintf(stderr, "log4c_appender_open failed for %s\n", app_name); - return NULL; - } + (void) log4c_appender_type_set(&log4c_appender_type_to_console); + (void) log4c_appender_type_set(&log4c_appender_type_to_syslog); + (void) log4c_appender_type_set(&log4c_appender_type_to_journal); - return appender; + + if (log4c_init()) + fprintf(stderr, "log4c_init() failed?!"); + + return; } -static rdk_Error rdk_dbg_priv_set_log_level(const char* category_name, rdk_LogLevel log_level) +rdk_Error rdk_dbg_priv_config(const char* debugConfigFile) { - const char* cat_name = category_name ? category_name : "LOG.RDK"; - log4c_category_t* cat = log4c_category_get(cat_name); - if (!cat) + rdk_Error ret = RDK_SUCCESS; + if (debugConfigFile) { - cat = log4c_category_new(cat_name); + gRootCat = log4c_category_get(gRootCatName); + if (!gRootCat) + { + gRootCat = log4c_category_new(gRootCatName); + /* Get the root category */ + if (!gRootCat) + { + fprintf(stderr, "RDK Root Category Creation failed?!"); + } + } + /* Read the config file & populate pre-configured log levels */ + ret = rdk_logger_parse_config(debugConfigFile); + /* Get the Root Priority */ + if (gRootCat) + gRootPriority = log4c_category_get_priority(gRootCat); } - if (cat) + else { - int log4c_prio = rdk_logLevel_to_log4c_priority(log_level); - log4c_category_set_priority(cat, log4c_prio); + fprintf(stderr, "Invalid conf file!"); + ret = RDK_FAILURE; } - return RDK_SUCCESS; + + return ret; } -/** - * @brief Initialize RDK logger with extended configuration. - * This is the ONLY public API for extended logger initialization. - */ -rdk_Error rdk_dbg_priv_ext_init(const rdk_logger_ext_config_t* config) -{ - char appender_name[256]; +rdk_Error rdk_dbg_priv_ext_init (const rdk_logger_ext_config_t* config) +{ + rdk_Error ret = RDK_SUCCESS; if (!config) { fprintf(stderr, "Error: config parameter is NULL\n"); return RDK_FAILURE; } - const char* cat_name = config->pCategoryName ? config->pCategoryName : "LOG.RDK"; - log4c_category_t* cat = log4c_category_get(cat_name); - if (!cat) - cat = log4c_category_new(cat_name); - if (!cat) - cat = gRootCat; - if (!cat) - { - fprintf(stderr, "Failed to get or create log category\n"); - return RDK_FAILURE; - } - if (config->appender == RDKLOG_OUTPUT_FILE && config->pFilePolicy == NULL) - { - fprintf(stderr, "Error: file appender requires non-NULL file policy\n"); - return RDK_FAILURE; - } - - log4c_appender_t* appender = rdk_dbg_priv_appender_init(cat_name, config->appender, - config->layout, config->pFilePolicy); - if (appender == NULL) + log4c_category_t* cat = NULL; + log4c_appender_t* app = NULL; + pthread_mutex_lock(&gLoggingMutex); + if (config->pModuleName) { - fprintf(stderr, "Failed to initialize appender for category %s\n", cat_name); - return RDK_FAILURE; + cat = log4c_category_get(config->pModuleName); } - log4c_category_set_appender(cat, appender); - log4c_category_set_additivity(cat, 0); - - rdk_Error result = rdk_dbg_priv_set_log_level(cat_name, config->loglevel); - if(result != RDK_SUCCESS) + else { - fprintf(stderr, "Failed to set log level for category %s\n", cat_name); - return result; + cat = gRootCat; } - return RDK_SUCCESS; -} - -/** - * Safely force a string to uppercase. I hate this mundane rubbish. - * - * @param token String to be forced to uppercase. - */ -static void forceUpperCase(char *token) -{ - while (*token) + if (cat) { - if (islower(*token)) + if ((RDKLOG_OUTPUT_FILE == config->output) && (config->pFilePolicy == NULL)) { - *token = (char) toupper(*token); + fprintf(stderr, "Error: file appender requires non-NULL file policy\n"); + app = NULL; } - token++; - } -} - -/** - * String names that correspond to the various logging types. - * Note: This array *must* match the RDK_LOG_* enum. - */ -const char *rdk_logLevelStrings[RDK_LOG_NONE] = -{ - "FATAL", - "ERROR", - "WARNING", - "NOTICE", - "INFO", - "DEBUG", - "TRACE", -}; - -/** - * Convert a log level name to the correspodning log level enum value. - * - * @param name Log level name, which must be uppercase. - * @param Corresponding enumeration value or -1 on error. - */ -static int logNameToEnum(const char *name) -{ - int i = 0; - while (i < RDK_LOG_NONE) - { - if (strcmp(name, rdk_logLevelStrings[i]) == 0) + else { - return i; - } - i++; - } + char app_name[128] = ""; + const char* cat_name = config->pModuleName ? config->pModuleName : gRootCatName; - return -1; -} + if (RDKLOG_OUTPUT_FILE == config->output) + { + snprintf(app_name, sizeof(app_name), "%s.file", cat_name); + } + else + { + snprintf(app_name, sizeof(app_name), "%s.print", cat_name); + } -static void printTime(const struct tm *pTm, char *pBuff) -{ - sprintf(pBuff,"%02d%02d%02d-%02d:%02d:%02d",pTm->tm_year + 1900 - 2000, pTm->tm_mon + 1, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec); -} + app = log4c_appender_get(app_name); -/***************************************************************************** - * - * EXPORTED FUNCTIONS - * - ****************************************************************************/ -void rdk_dbg_priv_config(void) -{ - int mod = 1; - const char *defaultValue = rdk_logger_envGet("LOG.RDK.DEFAULT"); - if (defaultValue && defaultValue[0] != 0) - { - char levelName[32]; - strncpy(levelName, defaultValue, sizeof(levelName)-1); - levelName[sizeof(levelName)-1] = '\0'; - forceUpperCase(levelName); + if (app) + { + if (RDKLOG_OUTPUT_CONSOLE == config->output) + { + log4c_appender_set_type(app, log4c_appender_type_get("to_console")); + } + else if (RDKLOG_OUTPUT_SYSLOG == config->output) + { + log4c_appender_set_type(app, log4c_appender_type_get("to_syslog")); + } + else if (RDKLOG_OUTPUT_JOURNAL == config->output) + { + /* Set the Appender Type */ + log4c_appender_set_type(app, log4c_appender_type_get("to_journal")); + } + else if (RDKLOG_OUTPUT_FILE == config->output) + { + rdk_LogOutput_File *pPolicy = config->pFilePolicy; + /* Close the Appender to complete the existing file writing; + * Also, if the appender is NOT opened yet, log4c will take care of + * returning without no-op */ + log4c_appender_close(app); + + rollingfile_udata_t *oldData = log4c_appender_get_udata(app); + if (oldData) + { + free(oldData); + log4c_appender_set_udata(app, NULL); + } - if (!gRootCat) - gRootCat = log4c_category_get("LOG.RDK"); + /* Set the Appender Type */ + log4c_appender_set_type(app, log4c_appender_type_get("rollingfile")); - if (!gRootCat) - { - printf("LOG.RDK.DEFAULT is not defined..\n"); - return; + rollingfile_udata_t *rudata = rollingfile_make_udata(); + if (rudata) + { + rollingfile_udata_set_logdir(rudata, pPolicy->fileLocation); + rollingfile_udata_set_files_prefix(rudata, pPolicy->fileName); + if (pPolicy->fileCountMax > 0) + { + long maxBytes = (pPolicy->fileSizeMax > 0) ? pPolicy->fileSizeMax : ROLLINGPOLICY_SIZE_DEFAULT_MAX_FILE_SIZE; + char policy_name[128]; + snprintf(policy_name, sizeof(policy_name), "%s.policy", app_name); + + log4c_rollingpolicy_t *policy = log4c_rollingpolicy_get(policy_name); + if (policy) + { + log4c_rollingpolicy_set_type(policy, log4c_rollingpolicy_type_get("sizewin")); + rollingpolicy_sizewin_udata_t *sizewin_udata = sizewin_make_udata(); + if (sizewin_udata) + { + sizewin_udata_set_file_maxsize(sizewin_udata, maxBytes); + sizewin_udata_set_max_num_files(sizewin_udata, pPolicy->fileCountMax); + log4c_rollingpolicy_set_udata(policy, sizewin_udata); + } + rollingfile_udata_set_policy(rudata, policy); + } + } + log4c_appender_set_udata(app, rudata); + } + } + } } - if (strcasecmp(levelName, "NONE") == 0) + if (app) { - log4c_category_set_priority(gRootCat, LOG4C_PRIORITY_NONE); + log4c_layout_t* layoutObj = NULL; + switch (config->format) + { + case RDKLOG_FORMAT_PLAINTEXT: + { + layoutObj = log4c_layout_get("rdk_plaintext"); + break; + } + case RDKLOG_FORMAT_WITH_TS: + { + layoutObj = log4c_layout_get("rdk_with_ts"); + break; + } + case RDKLOG_FORMAT_DETAIL_WITH_TS: + { + layoutObj = log4c_layout_get("rdk_detail_with_ts"); + break; + } + case RDKLOG_FORMAT_DETAIL_WITHOUT_TS: + { + layoutObj = log4c_layout_get("rdk_detail_without_ts"); + break; + } + default: + { + layoutObj = log4c_layout_get("rdk_plaintext"); + break; + } + } + if (layoutObj) + { + log4c_appender_set_layout(app, layoutObj); + } + + log4c_category_set_appender(cat, app); + log4c_category_set_additivity(cat, 0); + + log4c_priority_level_t prio = rdk_logLevel_to_log4c_priority(config->loglevel); + log4c_category_set_priority(cat, prio); } else { - int lvl = logNameToEnum(levelName); - if (lvl >= 0 && lvl < RDK_LOG_NONE) - { - log4c_category_set_priority(gRootCat, rdk_logLevel_to_log4c_priority(lvl)); - } + fprintf(stderr, "Failed to get or create log appender\n"); + ret = RDK_FAILURE; } - gRootPriority = log4c_category_get_priority(gRootCat); } else { - printf("LOG.RDK.DEFAULT is not defined..\n"); - return; + fprintf(stderr, "Failed to get or create log category\n"); + ret = RDK_FAILURE; } - for (mod = 1; mod <= global_count; mod++) - { - const char* modName = rdk_logger_envGetModFromNum(mod); - const char* modValue = rdk_logger_envGetValueFromNum(mod); - if (modName && modValue && modValue[0] != '\0') - { - char levelName[32]; - strncpy(levelName, modValue, sizeof(levelName)-1); - levelName[sizeof(levelName)-1] = '\0'; - forceUpperCase(levelName); + pthread_mutex_unlock(&gLoggingMutex); + return ret; +} - log4c_category_t* cat = log4c_category_get(modName); - if (cat) - { - if (strcasecmp(levelName, "NONE") == 0) - { - log4c_category_set_priority(cat, LOG4C_PRIORITY_NONE); - } - else - { - int lvl = logNameToEnum(levelName); - if (lvl >= 0 && lvl < RDK_LOG_NONE) - { - log4c_category_set_priority(cat, rdk_logLevel_to_log4c_priority(lvl)); - } - else - { - log4c_category_set_priority(cat, LOG4C_PRIORITY_NONE); - } - } - } - } - } +void rdk_dbg_priv_deinit() +{ + gRootCat = NULL; +} + +/** + * Format the time into a fixed-length ISO 8601-style timestamp. + * + */ +static void printTime(const struct tm *pTm, char *pBuff) +{ + sprintf(pBuff,"%02d-%02d-%02dT%02d:%02d:%02d",pTm->tm_year + 1900, pTm->tm_mon + 1, pTm->tm_mday, pTm->tm_hour, pTm->tm_min, pTm->tm_sec); } /** @@ -486,18 +545,37 @@ void rdk_dbg_priv_config(void) * @param[in] module The module name or category for which the log level shall be checked (as mentioned in debug.ini). * @param[in] level The debug logging level. * - * @return Returns TRUE, if debug log level enabled successfully else returns FALSE. + * @return Returns true, if debug log level enabled successfully else returns false. */ -rdk_logger_Bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level) +bool rdk_logger_is_logLevel_enabled(const char *module, rdk_LogLevel level) { - if(IS_LOGGING_ENABLED_FOR_LEVEL(module, level)) - { - return TRUE; - } - else - { - return FALSE; - } + bool isEnabled = false; + log4c_category_t* cat = NULL; + if (RDK_LOG_NONE == level) + { + return false; + } + else + { + + pthread_mutex_lock(&gLoggingMutex); + cat = log4c_category_get(module); + if (cat) + { + int log4cPriority = rdk_logLevel_to_log4c_priority(level); + if (log4c_category_is_priority_enabled(cat, log4cPriority)) + { + isEnabled = true; + } + } + else + { + /* Default case, return false */ + isEnabled = false; + } + pthread_mutex_unlock(&gLoggingMutex); + } + return isEnabled; } void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const char* format, va_list args) @@ -508,195 +586,138 @@ void rdk_dbg_priv_log_msg(rdk_LogLevel level, const char *module_name, const cha /* Handling process request here. This is not a blocking call and it shall return immediately */ rdk_dyn_log_process_pending_request(); - if (!format) + /* Check the incoming log level; dont print when it is RDK_LOG_NONE */ + if (RDK_LOG_NONE == level) { - fprintf(stderr, "Error: NULL format string passed to rdk_dbg_priv_log_msg\n"); return; } + pthread_mutex_lock(&gLoggingMutex); cat = log4c_category_get(module_name); - prio = log4c_category_get_priority(cat); - if (cat && prio == LOG4C_PRIORITY_NOTSET && gRootCat) { - log4c_category_set_priority(cat, log4c_category_get_priority(gRootCat)); - prio = gRootPriority; - } - if(!cat) { cat = gRootCat; } - - if(!cat) - { - return; - } - - if (!IS_LOGGING_ENABLED_FOR_LEVEL(module_name, level)) + else { - return; + prio = log4c_category_get_priority(cat); + if (LOG4C_PRIORITY_NOTSET == prio) + { + log4c_category_set_priority(cat, gRootPriority); + prio = gRootPriority; + } } - switch (level) + /* To Ensure that we dont log at all when category is invalid */ + if(cat) { - case RDK_LOG_FATAL: - log4c_category_vlog(cat, LOG4C_PRIORITY_FATAL, format, args); - break; - case RDK_LOG_ERROR: - log4c_category_vlog(cat, LOG4C_PRIORITY_ERROR, format, args); - break; - case RDK_LOG_WARN: - log4c_category_vlog(cat, LOG4C_PRIORITY_WARN, format, args); - break; - case RDK_LOG_NOTICE: - log4c_category_vlog(cat, LOG4C_PRIORITY_NOTICE, format, args); - break; - case RDK_LOG_INFO: - log4c_category_vlog(cat, LOG4C_PRIORITY_INFO, format, args); - break; - case RDK_LOG_DEBUG: - log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); - break; - case RDK_LOG_TRACE: - log4c_category_vlog(cat, LOG4C_PRIORITY_TRACE, format, args); - break; - default: - log4c_category_vlog(cat, LOG4C_PRIORITY_DEBUG, format, args); - break; - } -} - - -void rdk_dbg_priv_reconfig(const char *pModuleName, const char *pLogLevel) -{ - char logTypeName[20] = {'\0'}; + va_list localArg; + char logMsg[LOG4C_MSG_BUFFER_SIZE] = ""; + int n = 0; + int log4cPriority = rdk_logLevel_to_log4c_priority(level); - if ((NULL == pModuleName) || (NULL == pLogLevel)) - { - return; - } + va_copy(localArg, args); + n = vsnprintf(logMsg, LOG4C_MSG_BUFFER_SIZE, format, localArg); + va_end(localArg); - strncpy(logTypeName, pLogLevel, sizeof(logTypeName)-1); - if (logTypeName[0] == '~') - { - logTypeName[0] = '!'; - } + if (n > LOG4C_MSG_BUFFER_SIZE) + { + // Lets allocate the memory and split into multiple chunks of LOG4C_MSG_BUFFER_SIZE + char *p = (char*) malloc(n + 1); + if (p) + { + va_list reAllocArg; + int toPrint = 0; + int i = 0; - int disable = 0; - if (logTypeName[0] == '!') { - disable = 1; - memmove(logTypeName, logTypeName + 1, strlen(logTypeName)); - } + va_copy(reAllocArg, args); + n = vsnprintf(p, n+1, format, reAllocArg); + va_end(reAllocArg); - int prio = LOG4C_PRIORITY_INFO; // default - if (strcasecmp(logTypeName, "FATAL") == 0) prio = LOG4C_PRIORITY_FATAL; - else if (strcasecmp(logTypeName, "ERROR") == 0) prio = LOG4C_PRIORITY_ERROR; - else if (strcasecmp(logTypeName, "WARNING") == 0) prio = LOG4C_PRIORITY_WARN; - else if (strcasecmp(logTypeName, "NOTICE") == 0) prio = LOG4C_PRIORITY_NOTICE; - else if (strcasecmp(logTypeName, "INFO") == 0) prio = LOG4C_PRIORITY_INFO; - else if (strcasecmp(logTypeName, "DEBUG") == 0) prio = LOG4C_PRIORITY_DEBUG; - else if (strcasecmp(logTypeName, "TRACE") == 0) prio = LOG4C_PRIORITY_TRACE; - else if (strcasecmp(logTypeName, "NONE") == 0) prio = LOG4C_PRIORITY_NONE; - - log4c_category_t* cat = log4c_category_get(pModuleName); - if (cat) { - if (disable) { - log4c_category_set_priority(cat, gRootPriority); + for (i = 0; i < n; i += toPrint) + { + toPrint = ((n - i) < LOG4C_MSG_BUFFER_SIZE) ? (n - i) : LOG4C_MSG_BUFFER_SIZE; + log4c_category_log(cat, log4cPriority, "%.*s\n", toPrint, p+i); + } + free(p); + } } - else { - log4c_category_set_priority(cat, prio); + else + { + log4c_category_log(cat, log4cPriority, "%s", logMsg); } } -} + pthread_mutex_unlock(&gLoggingMutex); + return; +} -/*************************Copied from ri_log.c******************/ -/** - * Instantiate the logger... - * @param cat The category string for this instance logging/filtering - * @return the result of the instantiation - */ -static int initLogger(char *category) +bool rdk_dbg_priv_log_reconfig(const char *pModuleName, rdk_LogLevel logLevel) { + bool ret = true; + log4c_category_t* cat = NULL; + log4c_priority_level_t prio = gRootPriority; // default + prio = rdk_logLevel_to_log4c_priority(logLevel); - ///> These must be set before calling log4c_init so that the log4crc file - ///> will configure them - (void) log4c_appender_type_set(&log4c_appender_type_stream_env); - (void) log4c_appender_type_set(&log4c_appender_type_stream_env_append); - (void) log4c_appender_type_set(&log4c_appender_type_stream_env_plus_stdout); - (void) log4c_appender_type_set( - &log4c_appender_type_stream_env_append_plus_stdout); - (void) log4c_layout_type_set(&log4c_layout_type_dated_nocr); - (void) log4c_layout_type_set(&log4c_layout_type_basic_nocr); - (void) log4c_layout_type_set(&log4c_layout_type_comcast_dated_nocr); + pthread_mutex_lock(&gLoggingMutex); + if (pModuleName) + { + cat = log4c_category_get(pModuleName); - if (log4c_init()) + if (cat) { + log4c_category_set_priority(cat, prio); + } + } + else { - fprintf(stderr, "log4c_init() failed?!"); - return -1; + ret = false; } - return 0; -} + pthread_mutex_unlock(&gLoggingMutex); + return ret; +} /**************************************************************** - * Dated layout with no ending carriage return / line feed + * Plain Text format with no ending carriage return / line feed */ -static const char* dated_format_nocr(const log4c_layout_t* layout, - const log4c_logging_event_t* event) +static const char* rdk_plaintext(const log4c_layout_t* layout, const log4c_logging_event_t* event) { - struct tm tm; - char timeBuff[40]; - //localtime_r(&event->evt_timestamp.tv_sec, &tm); /* Use the UTC Time for logging */ - gmtime_r(&event->evt_timestamp.tv_sec, &tm); - - memset(&timeBuff,0,40); - - printTime(&tm,timeBuff); + (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s %s", + log4c_priority_to_string(event->evt_priority), + event->evt_msg); - (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, - "%s.%03ld %-8s %s- %s", timeBuff, - event->evt_timestamp.tv_usec / 1000, log4c_priority_to_string( - event->evt_priority), event->evt_category, - event->evt_msg); - if (event->evt_buffer.buf_size > 0 && event->evt_buffer.buf_data != NULL) - { - event->evt_buffer.buf_data[event->evt_buffer.buf_size - 1] = 0; - } return event->evt_buffer.buf_data; } +#define COMCAST_DATAED_BUFF_SIZE 40 /**************************************************************** - * Basic layout with no ending carriage return / line feed + * With TimeStamp format with no ending carriage return / line feed */ -static const char* basic_format_nocr(const log4c_layout_t* layout, - const log4c_logging_event_t* event) +static const char* rdk_with_ts(const log4c_layout_t* layout, const log4c_logging_event_t* event) { - (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%-8s %s - %s", - log4c_priority_to_string(event->evt_priority), - event->evt_category, event->evt_msg); + struct tm tm; + char timeBuff[COMCAST_DATAED_BUFF_SIZE] = {0}; - if (event->evt_buffer.buf_size > 0 && event->evt_buffer.buf_data != NULL) - { - event->evt_buffer.buf_data[event->evt_buffer.buf_size - 1] = 0; - } + gmtime_r(&event->evt_timestamp.tv_sec, &tm); + printTime(&tm,timeBuff); + + (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s.%06ld %s %s", timeBuff, + event->evt_timestamp.tv_usec, + log4c_priority_to_string(event->evt_priority), + event->evt_msg); return event->evt_buffer.buf_data; } -#define COMCAST_DATAED_BUFF_SIZE 40 - -static const char* comcast_dated_format_nocr(const log4c_layout_t* layout, - log4c_logging_event_t*event) +/**************************************************************** + * Detailed format with/without timestamp no ending carriage return / line feed + */ +static const char* rdk_detail_format_handler(const log4c_layout_t* layout, const log4c_logging_event_t* event, bool isTimed) { struct tm tm; - int n = -1; char timeBuff[COMCAST_DATAED_BUFF_SIZE] = {0}; - //localtime_r(&event->evt_timestamp.tv_sec, &tm); /* Use the UTC Time for logging */ - gmtime_r(&event->evt_timestamp.tv_sec, &tm); - - printTime(&tm,timeBuff); /** Get the last part of the cagetory as "module" */ char *p= (char *)(event->evt_category); @@ -720,238 +741,124 @@ static const char* comcast_dated_format_nocr(const log4c_layout_t* layout, } } - n = snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, - "%s.%06ld [mod=%s, lvl=%s] [tid=%ld] %s",timeBuff, - event->evt_timestamp.tv_usec, - p, log4c_priority_to_string(event->evt_priority), syscall(SYS_gettid), - event->evt_msg); - if (n > -1 && n > event->evt_buffer.buf_size && event->evt_buffer.buf_maxsize == 0) { - event->evt_buffer.buf_size = n + COMCAST_DATAED_BUFF_SIZE + 1; - event->evt_buffer.buf_data = (char *) realloc (event->evt_buffer.buf_data, event->evt_buffer.buf_size); - //TODO realloc error check - n = snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, - "%s.%06ld [mod=%s, lvl=%s] [tid=%ld] %s",timeBuff, - event->evt_timestamp.tv_usec, - p, log4c_priority_to_string(event->evt_priority), syscall(SYS_gettid), - event->evt_msg); + if (isTimed) + { + gmtime_r(&event->evt_timestamp.tv_sec, &tm); + printTime(&tm,timeBuff); + + (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s.%06ld %s [%s] [%ld] %s", + timeBuff, + event->evt_timestamp.tv_usec, + log4c_priority_to_string(event->evt_priority), + p, + syscall(SYS_gettid), + event->evt_msg); } - if (event->evt_buffer.buf_size > 0 && event->evt_buffer.buf_data != NULL) + else { - event->evt_buffer.buf_data[event->evt_buffer.buf_size - 1] = 0; + (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s [%s] [%ld] %s", + log4c_priority_to_string(event->evt_priority), + p, + syscall(SYS_gettid), + event->evt_msg); } + return event->evt_buffer.buf_data; } + + /**************************************************************** - * Stream layout that will parse environment variables from the - * stream name (env vars have a leading "$(" and end with )" + * Detailed format with timestamp */ -static int stream_env_open(log4c_appender_t* appender, int append) +static const char* rdk_detail_with_ts(const log4c_layout_t* layout, const log4c_logging_event_t* event) +{ + return rdk_detail_format_handler(layout, event, true); +} + +/**************************************************************** + * Detailed format without timestamp + */ +static const char* rdk_detail_without_ts(const log4c_layout_t* layout, const log4c_logging_event_t* event) +{ + return rdk_detail_format_handler(layout, event, false); +} + +/*****************************************************************/ +static int to_console_open(log4c_appender_t* appender) { FILE* fp = (FILE*)log4c_appender_get_udata(appender); - char* name = strdup(log4c_appender_get_name(appender)); - int nameLen = strlen(name); - char* temp = name; - char *varBegin, *varEnd; - char* envVar; - const int MAX_VAR_LEN = 1024; - char newName[MAX_VAR_LEN+1]; - int newNameLen = 0; if (fp) - { - free(name); /*RDKB-7467, CID-24968, free unused resources*/ return 0; - } - - newName[0] = '\0'; - - ///> Parse any environment variables - while ((varBegin = strchr(temp,'$')) != NULL) - { - ///> Search for opening and closing parens - if (((varBegin - name + 1) >= nameLen) || (*(varBegin+1) != '(')) - goto parse_error; - - ///> Append characters up to this point to the new name - strncat(newName, temp, varBegin-temp); - newNameLen += varBegin-temp; - if (newNameLen > MAX_VAR_LEN) - goto length_error; - - varBegin += 2; ///> start of env var name - - if ((varEnd = strchr(varBegin,')')) == NULL) - goto parse_error; - - *varEnd = '\0'; - if ((envVar = getenv(varBegin)) == NULL) - goto parse_error; - - ///> Append env var value to the new name - if((newNameLen + strlen(envVar)) < MAX_VAR_LEN){ - strncat(newName, envVar, strlen(envVar)); - newNameLen += strlen(envVar); - } - else{ - goto length_error; - } - temp = varEnd + 1; - } - - ///> Append remaining characters - if (newNameLen + (name + nameLen) - temp > MAX_VAR_LEN) - goto length_error; - strncat(newName, temp, (name + nameLen) - temp); - newNameLen += (name + nameLen) - temp; - - free(name); - - if (!strcmp(newName,"stderr")) - fp = stderr; - else if (!strcmp(newName,"stdout")) - fp = stdout; - else if (strlen(newName) >= strlen(".stdout") && - strcmp(newName + strlen(newName) - strlen(".stdout"), ".stdout") == 0) - fp = stdout; - else if (append) - { - printf("****Opening %s in append mode\n", newName); - if ((fp = fopen(newName, "a")) == NULL) - return -1; - } else - { - printf("****Opening %s in write mode\n", newName); - if ((fp = fopen(newName, "w")) == NULL) - return -1; - } + fp = stdout; - /**> unbuffered mode */ + /** Set unbuffered mode */ setbuf(fp, NULL); (void)log4c_appender_set_udata(appender, fp); return 0; - - parse_error: - fprintf(stderr, "*(*(*(*( log4c appender stream_env, %s -- Illegal env var name or format! %s\n", - __FUNCTION__, name); - (void)fflush(stderr); - free(name); - return -1; - - length_error: - fprintf(stderr, "*(*(*(*( log4c appender stream_env, %s -- Path is too long! %s\n", - __FUNCTION__, name); - (void)fflush(stderr); - free(name); - return -1; } -static int stream_env_overwrite_open(log4c_appender_t* appender) +static int to_console_append(log4c_appender_t* appender, const log4c_logging_event_t* event) { - return stream_env_open(appender, 0); + FILE* fp = (FILE*)log4c_appender_get_udata(appender); + + if (!fp) + fp = stdout; + + fprintf(fp, "%s", event->evt_rendered_msg); + (void)fflush(fp); + + return 0; } -static int stream_env_append_open(log4c_appender_t* appender) +static int to_console_close(log4c_appender_t* appender) { - return stream_env_open(appender, 1); + (void) appender; + return 0; } -#ifdef SYSTEMD_JOURNAL -static int stream_env_append_get_priority(int log4c_pr) +static int to_syslog_open(log4c_appender_t * appender) { - int priority; - switch(log4c_pr) - { - case LOG4C_PRIORITY_FATAL: - priority = LOG_EMERG; - break; - case LOG4C_PRIORITY_ERROR: - priority = LOG_ERR; - break; - case LOG4C_PRIORITY_WARN: - priority = LOG_WARNING; - break; - case LOG4C_PRIORITY_NOTICE: - priority = LOG_NOTICE; - break; - case LOG4C_PRIORITY_INFO: - priority = LOG_INFO; - break; - case LOG4C_PRIORITY_DEBUG: - case LOG4C_PRIORITY_TRACE: - default: - priority = LOG_DEBUG; - break; - } - return priority; +#ifdef HAVE_SYSLOG_H + openlog(NULL, LOG_PID, LOG_USER); +#endif /* HAVE_SYSLOG_H */ + return 0; } -#endif -static int stream_env_append(log4c_appender_t* appender, - const log4c_logging_event_t* event) +static int to_syslog_append(log4c_appender_t* appender, const log4c_logging_event_t* event) { - int retval=0; - FILE* fp = (FILE*)log4c_appender_get_udata(appender); - -#if defined(SYSTEMD_SYSLOG_HELPER) - send_logs_to_syslog(event->evt_rendered_msg); -#elif defined(SYSTEMD_JOURNAL) - if (fp == stdout || fp == stderr) - { - retval = sd_journal_print(stream_env_append_get_priority(event->evt_priority), "%s",event->evt_rendered_msg); - } - else - { - retval = fprintf(fp, "%s", event->evt_rendered_msg); - (void)fflush(fp); - } -#else - retval = fprintf(fp, "%s", event->evt_rendered_msg); - (void)fflush(fp); -#endif - - //free((void *)event->evt_rendered_msg); - - return retval; +#ifdef HAVE_SYSLOG_H + syslog(get_syslog_priority(event->evt_priority), "%s", event->evt_rendered_msg); +#endif /* HAVE_SYSLOG_H */ + return 0; } -static int stream_env_plus_stdout_append(log4c_appender_t* appender, - const log4c_logging_event_t* event) +static int to_syslog_close(log4c_appender_t * appender) { - int retval=0; - FILE* fp = (FILE*)log4c_appender_get_udata(appender); - -#if defined(SYSTEMD_SYSLOG_HELPER) - send_logs_to_syslog(event->evt_rendered_msg); -#elif defined(SYSTEMD_JOURNAL) - if (fp != stdout || fp != stderr) - { - retval = fprintf(fp, "%s", event->evt_rendered_msg); - } - else - { - retval = sd_journal_print(stream_env_append_get_priority(event->evt_priority), "%s",event->evt_rendered_msg); - } - (void)fflush(fp); -#else - retval = fprintf(fp, "%s", event->evt_rendered_msg); - fprintf(stdout, "%s", event->evt_rendered_msg); - (void)fflush(fp); - (void)fflush(stdout); -#endif - //free((void *)event->evt_rendered_msg); - - return retval; + (void) appender; + return 0; } - -static int stream_env_close(log4c_appender_t* appender) +static int to_journal_open(log4c_appender_t * appender) { - FILE* fp = (FILE*)log4c_appender_get_udata(appender); + (void) appender; + return 0; +} - if (!fp || fp == stdout || fp == stderr) +static int to_journal_append(log4c_appender_t* appender, const log4c_logging_event_t* event) +{ +#ifdef HAVE_SYSTEMD + sd_journal_print(get_syslog_priority(event->evt_priority), "%s", event->evt_rendered_msg); +#endif /* HAVE_SYSTEMD */ return 0; +} - return fclose(fp); +static int to_journal_close(log4c_appender_t * appender) +{ + (void) appender; + return 0; } + +/* End Of File */ diff --git a/src/rdk_dynamic_logger.c b/src/rdk_dynamic_logger.c index 95de593..7b9ecf7 100644 --- a/src/rdk_dynamic_logger.c +++ b/src/rdk_dynamic_logger.c @@ -30,6 +30,7 @@ #include #include "rdk_dynamic_logger.h" +#include "rdk_debug_priv.h" #define DL_PORT 12035 #define DL_SIGNATURE "COMC" @@ -38,43 +39,26 @@ static int g_dl_socket = -1; extern char *__progname; -static char * rdk_dyn_log_logLevelToString(unsigned char log_level) +static char * rdk_dyn_log_logLevelToString(rdk_LogLevel log_level) { - int negate = 0; - unsigned char negate_mask = 0x80; - - if(negate_mask == (log_level & negate_mask)) { - negate = 1; - log_level = log_level & (~negate_mask) ; - } - switch(log_level){ - case RDK_LOG_FATAL: - return (negate) ? "!FATAL":"FATAL"; - case RDK_LOG_ERROR: - return (negate) ? "!ERROR":"ERROR"; - case RDK_LOG_WARN: - return (negate) ? "!WARNING":"WARNING"; - case RDK_LOG_NOTICE: - return (negate) ? "!NOTICE":"NOTICE"; - case RDK_LOG_INFO: - return (negate) ? "!INFO":"INFO"; - case RDK_LOG_DEBUG: - return (negate) ? "!DEBUG":"DEBUG"; - case RDK_LOG_TRACE: - return (negate) ? "!TRACE":"TRACE"; - case RDK_LOG_NONE: - return "NONE"; + case RDK_LOG_FATAL: return "FATAL"; + case RDK_LOG_ERROR: return "ERROR"; + case RDK_LOG_WARN: return "WARNING"; + case RDK_LOG_NOTICE: return "NOTICE"; + case RDK_LOG_INFO: return "INFO"; + case RDK_LOG_DEBUG: return "DEBUG"; + case RDK_LOG_TRACE: return "TRACE"; + case RDK_LOG_NONE: return "NONE"; } - - return NULL; + return "NONE"; } static void rdk_dyn_log_validate_component_name(const unsigned char *buf) { unsigned char log_level = 0; int app_len, comp_len, i = DL_SIGNATURE_LEN; - char *loggingLevel = NULL, comp_name[64] = {0}; + char comp_name[64] = {0}; if(0 != memcmp(buf,DL_SIGNATURE,i)) { return; @@ -91,12 +75,20 @@ static void rdk_dyn_log_validate_component_name(const unsigned char *buf) i += app_len; comp_len = buf[i]; - loggingLevel = rdk_dyn_log_logLevelToString(log_level); - if(NULL != loggingLevel) { + rdk_LogLevel loggingLevel = (rdk_LogLevel) log_level; + + if((loggingLevel >= RDK_LOG_FATAL) && (loggingLevel <= RDK_LOG_NONE)) + { memcpy(comp_name,buf+(++i),comp_len); - rdk_dbg_priv_reconfig(comp_name, loggingLevel); - fprintf(stderr,"%s(): Set %s loglevel for the component %s of the process %s\n",__func__,loggingLevel,comp_name,__progname); + rdk_dbg_priv_log_reconfig(comp_name, loggingLevel); + fprintf(stderr, "Log level change request to %s (%u) for the component %s, is success\n", rdk_dyn_log_logLevelToString(loggingLevel), loggingLevel, comp_name); + } + else + { + fprintf(stderr, "Log level change request with Invalid input (%u)\n", loggingLevel); } + + return; } void rdk_dyn_log_process_pending_request() @@ -176,7 +168,7 @@ void rdk_dyn_log_init() return; } - fprintf(stderr, "%sg_dl_socket = %d __progname = %s \n",__func__,g_dl_socket,__progname); + //fprintf(stderr, "%sg_dl_socket = %d __progname = %s \n",__func__,g_dl_socket,__progname); } void rdk_dyn_log_deinit() diff --git a/src/rdk_logger_init.c b/src/rdk_logger_init.c index 283ab42..687377a 100644 --- a/src/rdk_logger_init.c +++ b/src/rdk_logger_init.c @@ -34,14 +34,23 @@ #include #include #include -#include +#include #include "rdk_logger.h" -#include "rdk_error.h" #include "rdk_debug_priv.h" #include "rdk_dynamic_logger.h" -#include "rdk_utils.h" -#define BUF_LEN 256 -static int isLogInited = 0; + +static pthread_mutex_t gInitMutex = PTHREAD_MUTEX_INITIALIZER; + +bool isLogInited = false; + +static void __attribute__((constructor)) _rdk_logger_init (void) +{ + /* Perform Logger Internal Init */ + rdk_dbg_priv_init(); + + return; +} + /** * @brief Initialize the logger. Sets up the environment variable storage by parsing * debug configuration file then Initialize the debug support to the underlying platform. @@ -55,71 +64,55 @@ static int isLogInited = 0; */ rdk_Error rdk_logger_init(const char* debugConfigFile) { - rdk_Error ret; - - if (0 == isLogInited) + rdk_Error ret = RDK_SUCCESS; + pthread_mutex_lock(&gInitMutex); + if (!isLogInited) { if (NULL == debugConfigFile) { debugConfigFile = DEBUG_CONF_FILE; } - /* Read the config file & populate pre-configured log levels */ - ret = rdk_logger_parse_config(debugConfigFile); - if ( RDK_SUCCESS != ret) + /* Perform Logger Internal Init */ + ret = rdk_dbg_priv_config(debugConfigFile); + + if (RDK_SUCCESS == ret) { - printf("%s:%d Adding debug config file %s failed\n", __FUNCTION__, __LINE__, debugConfigFile); - return ret; + /* Perform Dynamic Logger Internal Init */ + rdk_dyn_log_init(); + + isLogInited = true; + /** + * Requests not to send SIGPIPE on errors on stream oriented + * sockets when the other end breaks the connection. The EPIPE + * error is still returned. + */ + signal(SIGPIPE, SIG_IGN); + } + else + { + printf("Parsing debug config file %s failed\n", debugConfigFile); } - /* Perform Logger Internal Init */ - rdk_dbg_init(); - - /* Perform Dynamin Logger Internal Init */ - rdk_dyn_log_init(); - - /** - * Requests not to send SIGPIPE on errors on stream oriented - * sockets when the other end breaks the connection. The EPIPE - * error is still returned. - */ - signal(SIGPIPE, SIG_IGN); - isLogInited = 1; } - return RDK_SUCCESS; + pthread_mutex_unlock(&gInitMutex); + return ret; } -/** - * @brief Initialize RDK logger with extended configuration. - * - * This function provides a comprehensive logger initialization interface that combines - * the standard RDK logger initialization with extended configuration options. It first - * calls RDK_LOGGER_INIT() to perform basic logger setup, then applies the extended - * configuration parameters for specific module logging requirements. - * - * @param[in] config Pointer to extended logger configuration structure containing: - * - pCategoryName: Log category/module name (required, cannot be NULL) - * - loglevel: Default log level for the category - * - appender: Type of log appender - * - layout: Message layout format - * - pFilePolicy: File policy configuration (required for file appenders, NULL for others) - * - * @return RDK_SUCCESS on successful initialization, RDK_FAILURE on error. - * - * @note This function must be called after the basic RDK logger system is available. - * @note If RDK_LOGGER_INIT() fails, the extended configuration is not applied. - * @note For file appenders, ensure the log directory exists and has write permissions. - * @note This function internally calls rdk_dbg_priv_ext_init() for the actual configuration. - */ rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config) { - rdk_Error ret; + rdk_Error ret = RDK_SUCCESS; + ret = RDK_LOGGER_INIT(); - if (ret == RDK_SUCCESS) + + if (RDK_SUCCESS == ret) { + pthread_mutex_lock(&gInitMutex); ret = rdk_dbg_priv_ext_init(config); + pthread_mutex_unlock(&gInitMutex); } + return ret; - } +} /** * @brief Cleanup the logger instantiation. @@ -128,12 +121,12 @@ rdk_Error rdk_logger_ext_init(const rdk_logger_ext_config_t* config) */ rdk_Error rdk_logger_deinit() { - if(isLogInited) + pthread_mutex_lock(&gInitMutex); + if (isLogInited) { rdk_dyn_log_deinit(); - rdk_logger_release_config(); - //isLogInited = 0; } + pthread_mutex_unlock(&gInitMutex); return RDK_SUCCESS; } diff --git a/src/rdk_logger_milestone.c b/src/rdk_logger_milestone.c index 8ca4d8a..418f2fe 100644 --- a/src/rdk_logger_milestone.c +++ b/src/rdk_logger_milestone.c @@ -20,15 +20,12 @@ #include #include #include -#include #include #include #include "rdk_logger_milestone.h" -#ifdef LOGMILESTONE +#ifndef MILESTONE_LOG_FILENAME #define MILESTONE_LOG_FILENAME "/opt/logs/rdk_milestones.log" -#else -#define MILESTONE_LOG_FILENAME "/rdklogs/logs/rdk_milestones.log" #endif unsigned long long getUptimeMS(void) diff --git a/src/rdk_logger_util.c b/src/rdk_logger_util.c deleted file mode 100644 index 5727f62..0000000 --- a/src/rdk_logger_util.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * If not stated otherwise in this file or this component's LICENSE file the - * following copyright and licenses apply: - * - * Copyright 2016 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -/** - * @file rdk_logger_util.c - * This source file contains the APIs for RDK logger util. - */ - -/* - * This file provides the rdk_logger_ utility APIs. - */ - -/* Header Files */ -#include /* Resolve basic type references. */ -#include "rdk_logger.h" /* Resolved RDK_LOG support. */ -#include "rdk_error.h" -#include "rdk_utils.h" - -#include -#include -#include -#include - -/*Resolve reboot and related macros.*/ -#include -#include -#include - - -typedef struct EnvVarNode -{ - int number; - char* name; - char* value; - struct EnvVarNode *next; -} EnvVarNode; - -/** Global count for the modules */ -int global_count; -static int number = 0; - -/* Env var cache */ -static EnvVarNode *g_envCache = NULL; - -static void trim(char *instr, char* outstr) -{ - char *ptr = instr; - char *endptr = instr + strlen(instr)-1; - int length; - - /* Advance pointer to first non-whitespace char */ - while (isspace(*ptr)) - ptr++; - - if (ptr > endptr) - { - /* - * avoid breaking things when there are - * no non-space characters in instr (JIRA OCORI-2028) - */ - outstr[0] = '\0'; - return; - } - - /* Move end pointer toward the front to first non-whitespace char */ - while (isspace(*endptr)) - endptr--; - - length = endptr + 1 - ptr; - strncpy(outstr,ptr,length); - outstr[length] = '\0'; - -} - -/** - * @brief This Function removes the node contents while exit - * - * @return Returns Returns RDK_SUCCESS if the setting of environment variable is successful else it returns -1. - */ -rdk_Error rdk_logger_release_config() -{ - EnvVarNode *currentNode; - EnvVarNode *nextNode; - - currentNode = g_envCache; - while(currentNode != NULL) - { - nextNode = currentNode->next; - if(currentNode->name != NULL) - free(currentNode->name); - if(currentNode->value != NULL) - free(currentNode->value); - free(currentNode); - currentNode = nextNode; - } - g_envCache = NULL; - number = 0; - global_count = number; - return RDK_SUCCESS; -} - -/** - * @brief This Function sets up the environment variable cache by parsing configuration file and adding - * each name/value pairs to the list. - * - * @param[in] path Path of the configuration file. - * @return Returns Returns RDK_SUCCESS if the setting of environment variable is successful else it returns -1. - */ -rdk_Error rdk_logger_parse_config( const char * path) -{ - const int line_buf_len = 256; - - FILE* f; - char lineBuffer[line_buf_len]; - - /* Open the env file */ - if ((f = fopen( path,"r")) == NULL) - { - printf("***************************************************\n"); - printf("***************************************************\n"); - printf("** ERROR! Could not open configuration file! **\n"); - printf("***************************************************\n"); - printf("***************************************************\n"); - printf("(Tried %s\n", path); - return -1; - } - printf("Conf file %s open success\n", path); - - /* Read each line of the file */ - while (fgets(lineBuffer,line_buf_len,f) != NULL) - { - char name[line_buf_len]; - char value[line_buf_len]; - char trimname[line_buf_len]; - char trimvalue[line_buf_len]; - EnvVarNode *node; - EnvVarNode *tmp_node; - char *equals; - int length; - - /* Ignore comment lines */ - if (lineBuffer[0] == '#') - continue; - - /* Ignore lines that do not have an '=' char */ - if ((equals = strchr(lineBuffer,'=')) == NULL) - continue; - - /* Read the property and store in the cache */ - length = equals - lineBuffer; - strncpy( name,lineBuffer,length); - name[ length] = '\0'; /* have to null-term */ - - length = lineBuffer + strlen(lineBuffer) - equals + 1; - strncpy( value,equals+1,length); - value[ length] = '\0' ; - - /* Trim all whitespace from name and value strings */ - trim( name,trimname); - trim( value,trimvalue); - - tmp_node = g_envCache; - while(tmp_node) - { - if(strcmp(tmp_node->name, trimname) == 0) - { - break; - } - tmp_node = tmp_node->next; - } - - if(!tmp_node) - { - node = ( EnvVarNode*)malloc(sizeof(EnvVarNode)); - node->name = strdup( trimname); - node->value = strdup( trimvalue); - } - else - { - free(tmp_node->value); - tmp_node->value = strdup( trimvalue); - continue; - } - -#define COMP_SIGNATURE "LOG.RDK." -#define COMP_SIGNATURE_LEN 8 - /** Update number only for the modules, not for environment variable */ - if ((strcmp("LOG.RDK.DEFAULT", node->name) != 0) && - (strncmp(COMP_SIGNATURE, node->name, COMP_SIGNATURE_LEN) == 0)) - { - number++; - node->number = number; - } else - node->number = 0; - - /* Insert at the front of the list */ - node->next = g_envCache; - g_envCache = node; - } - - global_count = number; - - fclose( f); - return RDK_SUCCESS; -} - -/** - * @brief This function will get value of the specified environment variable. - * - * @param[in] name It is a pointer to the name of the target environment variable. - * - * @return Returns a pointer to the associated string value of the target environment - * variable or return NULL if the variable can't be found. - */ -const char* rdk_logger_envGet(const char *name) -{ - EnvVarNode *node = g_envCache; - - while (node != NULL) - { - /* Env var name match */ - if (strcmp(name,node->name) == 0) - { - /* return the value */ - return node->value; - } - - node = node->next; - } - - /* Not found */ - return NULL; -} - -/** - * @brief This function is used to get the value of the specified environment variable based - * on its registered number. - * - * @param[in] number Is a registered number of the target environment variable. - * @return Returns a pointer to the associated string value of the target environment. - * variable or return NULL in failure condition. - */ -const char* rdk_logger_envGetValueFromNum(int number) -{ - EnvVarNode *node = g_envCache; - - while (node != NULL) - { - /* Env var name match */ - if (number == node->number) - { - /* return the value */ - return node->value; - } - - node = node->next; - } - - /* Not found */ - return NULL; -} - -/** - * @brief Function will give the registered number of the specified environment variable. - * - * @param[in] mod It is a pointer to the name of the target environment variable. - * @return Returns an integer value if the call is success otherwise returns -1. - */ -int rdk_logger_envGetNum(const char * mod) -{ - EnvVarNode *node = g_envCache; - - while (node != NULL) - { - /* Env var name match */ - if (strcmp(mod,node->name) == 0) - { - /* return the value */ - return node->number; - } - - node = node->next; - } - - /* Not found */ - return -1; -} - -/** - * @brief This function is used to get the name of the specified environment variable based - * on its registered number. - * - * @param[in] Num Is a registered number of the target environment variable. - * @return Returns a pointer to the associated string value of the target environment variable associated - * for registered number. Return NULL if the environment variable can't be found for registered number. - */ -const char* rdk_logger_envGetModFromNum(int Num) -{ - EnvVarNode *node = g_envCache; - - while (node != NULL) - { - /* Env var name match */ - if (Num == node->number) - { - /* return the value */ - return node->name; - } - - node = node->next; - } - - /* Not found */ - return NULL; -} - -char* rdk_loglevelToString(rdk_LogLevel log_level, rdk_logger_Bool isLogEnabled) -{ - switch(log_level){ - case RDK_LOG_FATAL: - return (isLogEnabled) ? "FATAL":"!FATAL"; - case RDK_LOG_ERROR: - return (isLogEnabled) ? "ERROR":"!ERROR"; - case RDK_LOG_WARN: - return (isLogEnabled) ? "WARNING":"!WARNING"; - case RDK_LOG_NOTICE: - return (isLogEnabled) ? "NOTICE":"!NOTICE"; - case RDK_LOG_INFO: - return (isLogEnabled) ? "INFO":"!INFO"; - case RDK_LOG_DEBUG: - return (isLogEnabled) ? "DEBUG":"!DEBUG"; - case RDK_LOG_TRACE: - return (isLogEnabled) ? "TRACE":"!TRACE"; - case RDK_LOG_NONE: - return "NONE"; - } - - return NULL; -} - - - -/***/ diff --git a/test/Makefile.am b/test/Makefile.am index 6dad816..e8f6cf1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -20,11 +20,12 @@ SUBDIRS = DIST_SUBDIRS = -bin_PROGRAMS = dynamicLoggerTest +bin_PROGRAMS = testProgram + +testProgram_SOURCES= rdk_logger_debug_test.c rdk_logger_test_main.c +testProgram_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src/include -I./usr/include +testProgram_LDADD = $(top_builddir)/src/librdkloggers.la $(LOG4C_LIBS) +testProgram_LDFLAGS = -L/usr/lib + -dynamicLoggerTest_SOURCES=rdk_dynamic_logger_test.c -dynamicLoggerTest_LDADD = -L../src/util/.libs -lloggerutil -lIARMBus -dynamicLoggerTest_CPPFLAGS = -I$(top_srcdir)/include -dynamicLoggerTest_CFLAGS = -I./usr/include -I=/usr/include/rdk/iarmbus -dynamicLoggerTest_LDFLAGS = -I./usr/lib diff --git a/test/rdk_dynamic_logger_test.c b/test/rdk_dynamic_logger_test.c deleted file mode 100644 index 256c17f..0000000 --- a/test/rdk_dynamic_logger_test.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * If not stated otherwise in this file or this component's LICENSE file the - * following copyright and licenses apply: - * - * Copyright 2016 RDK Management - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#include -#include "libIBus.h" -#include "rdk_log_reg.h" - - -/* -To build the test app, add test folder to the below lines -SUBDIRS = src include test -DIST_SUBDIRS = cfg src include test -To the file rdk_logger/generic/Makefile.am - -How to test : - -1. Run the test App dynamicLoggerTest in the box. -The binary can be copied to the box after compiling the test code by doing a bitbake for rdk-logger -with the above changes. -2. The test application has registered for dynamic logging updates with -Application Name : - Application1 -Module Name ------ SubModule Name ------ Registered Callback -ClosedCaptions1 NULL CC_LOG_ControlCB1 -ClosedCaptions2 NULL CC_LOG_ControlCB2 -ServiceManager devicesettings CC_LOG_ControlCB3 -ServiceManager hdmicec CC_LOG_ControlCB4 - -Or - -Application Name : - Application2 -Module Name ------ SubModule Name ------ Registered Callback -ClosedCaptions1 NULL CC_LOG_CallBack1 -ClosedCaptions2 NULL CC_LOG_CallBack2 -ServiceManager devicesettings CC_LOG_CallBack3 -ServiceManager hdmicec CC_LOG_CallBack4 - -3. Execute the rdklogctrl tool with proper input parameters and check whether the -test application is showing correct print. - -eg. If we execute the tool with following parameters -./rdklogctrl Application1 ClosedCaptions1 NULL DEBUG ON - -The test application will print -TEST : CC_LOG_ControlCB1 called for ClosedCaptions1 -TEST : ##############Data obtained ################ -TEST : moduleName : ClosedCaptions1 subComponentName : NULL loggingLevel : DEBUG log_status : 1 - -Similarly different combinations of input parameters can be tested. - -*/ - -void CC_LOG_ControlCB1(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) -{ - printf("TEST : CC_LOG_ControlCB1 called for ClosedCaptions1\n"); - printf("TEST : ##############Data obtained ################\n"); - printf("TEST : moduleName : %s subComponentName : %s loggingLevel : %s log_status : %d\n",moduleName,subComponentName,loggingLevel,log_status); -} -void CC_LOG_ControlCB2(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) -{ - printf("TEST : CC_LOG_ControlCB2 called for ClosedCaptions2\n"); - printf("TEST : ##############Data obtained ################\n"); - printf("TEST : moduleName : %s subComponentName : %s loggingLevel : %s log_status : %d\n",moduleName,subComponentName,loggingLevel,log_status); -} -void CC_LOG_ControlCB3(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) -{ - printf("TEST : CC_LOG_ControlCB3 called for ServiceManager devicesettings\n"); - printf("TEST : ##############Data obtained ################\n"); - printf("TEST : moduleName : %s subComponentName : %s loggingLevel : %s log_status : %d\n",moduleName,subComponentName,loggingLevel,log_status); -} -void CC_LOG_ControlCB4(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) -{ - printf("TEST : CC_LOG_ControlCB4 called for ServiceManager hdmicec\n"); - printf("TEST : ##############Data obtained ################\n"); - printf("TEST : moduleName : %s subComponentName : %s loggingLevel : %s log_status : %d\n",moduleName,subComponentName,loggingLevel,log_status); -} -void CC_LOG_CallBack1(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) -{ - printf("TEST : CC_LOG_CallBack1 called for ClosedCaptions1\n"); - printf("TEST : ##############Data obtained ################\n"); - printf("TEST : moduleName : %s subComponentName : %s loggingLevel : %s log_status : %d\n",moduleName,subComponentName,loggingLevel,log_status); -} -void CC_LOG_CallBack2(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) -{ - printf("TEST : CC_LOG_CallBack2 called for ClosedCaptions2\n"); - printf("TEST : ##############Data obtained ################\n"); - printf("TEST : moduleName : %s subComponentName : %s loggingLevel : %s log_status : %d\n",moduleName,subComponentName,loggingLevel,log_status); -} -void CC_LOG_CallBack3(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) -{ - printf("TEST : CC_LOG_CallBack3 called for ServiceManager devicesettings\n"); - printf("TEST : ##############Data obtained ################\n"); - printf("TEST : moduleName : %s subComponentName : %s loggingLevel : %s log_status : %d\n",moduleName,subComponentName,loggingLevel,log_status); -} -void CC_LOG_CallBack4(const char *moduleName, const char *subComponentName, const char *loggingLevel, int log_status) -{ - printf("TEST : CC_LOG_CallBack4 called for ServiceManager hdmicec\n"); - printf("TEST : ##############Data obtained ################\n"); - printf("TEST : moduleName : %s subComponentName : %s loggingLevel : %s log_status : %d\n",moduleName,subComponentName,loggingLevel,log_status); -} - -#define IARM_BUS_DYNAMIC_LOGGER_TESTAPP "LOG_TESTER" - -void main() -{ - IARM_Bus_Init(IARM_BUS_DYNAMIC_LOGGER_TESTAPP); - IARM_Bus_Connect(); - rdk_logger_initialize(); - int i; - - printf("Thanks for using Dynamic Logger TestApp \n"); - printf("Please select the App name\n 1 - Application1 2 - Application2 \n"); - scanf("%d", &i); - - switch(i) - { - case 1: - - printf("Registering app Application1 \n"); - rdk_logger_setAppName("Application1"); - rdk_logger_registerLogCtrlComp("ClosedCaption1", NULL, CC_LOG_ControlCB1); - rdk_logger_registerLogCtrlComp("ClosedCaption2", NULL, CC_LOG_ControlCB2); - rdk_logger_registerLogCtrlComp("ServiceManager", "devicesettings", CC_LOG_ControlCB3); - rdk_logger_registerLogCtrlComp("ServiceManager", "hdmicec", CC_LOG_ControlCB4); - - break; - - case 2 : - - printf("Registering app Application2 \n"); - rdk_logger_setAppName("Application2"); - rdk_logger_registerLogCtrlComp("ClosedCaption1", NULL, CC_LOG_CallBack1); - rdk_logger_registerLogCtrlComp("ClosedCaption2", NULL, CC_LOG_CallBack2); - rdk_logger_registerLogCtrlComp("ServiceManager", "devicesettings", CC_LOG_CallBack3); - rdk_logger_registerLogCtrlComp("ServiceManager", "hdmicec", CC_LOG_CallBack4); - - break; - - default: - break; - } - while(1) - { - sleep(10); - } - - rdk_logger_unRegisterLogCtrlComp("ServiceManager", "hdmicec"); - rdk_logger_unRegisterLogCtrlComp("ClosedCaption2", NULL); - rdk_logger_unRegisterLogCtrlComp("ClosedCaption1", NULL); - rdk_logger_unRegisterLogCtrlComp("ServiceManager", "devicesettings"); - - rdk_logger_unInitialize(); - IARM_Bus_Disconnect(); - IARM_Bus_Term(); - return; -} diff --git a/test/rdk_logger_debug_test.c b/test/rdk_logger_debug_test.c index ac21bff..1aeae71 100644 --- a/test/rdk_logger_debug_test.c +++ b/test/rdk_logger_debug_test.c @@ -19,147 +19,43 @@ #include #include +#include #include "rdk_logger.h" int rdk_logger_debug_test() { - RDK_LOG(RDK_LOG_FATAL, "LOG.RDK.GFX", - "Fatal\n"); - - RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.GFX", - "Error\n"); - - RDK_LOG(RDK_LOG_WARN, "LOG.RDK.GFX", - "Warning\n"); - - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.GFX", - "Info\n"); - - RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.GFX", - "Notice\n"); - - RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.GFX", - "Debug\n"); - - RDK_LOG(RDK_LOG_TRACE, "LOG.RDK.GFX", - "Trace1\n"); - - RDK_LOG(RDK_LOG_FATAL, "LOG.RDK.SYS", - "Fatal\n"); - - RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.SYS", - "Error\n"); - - RDK_LOG(RDK_LOG_WARN, "LOG.RDK.SYS", - "Warning\n"); - - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.SYS", - "Info\n"); - - RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.SYS", - "Notice\n"); - - RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.SYS", - "Debug\n"); - - RDK_LOG(RDK_LOG_TRACE, "LOG.RDK.SYS", - "Trace1\n"); - - RDK_LOG(RDK_LOG_FATAL, "LOG.RDK.QAMSRC", - "Fatal\n"); - - RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.QAMSRC", - "Error\n"); - - RDK_LOG(RDK_LOG_WARN, "LOG.RDK.QAMSRC", - "Warning\n"); - - RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.QAMSRC", - "Notice\n"); - - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.QAMSRC", - "Info\n"); - - RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.QAMSRC", - "Debug\n"); - - RDK_LOG(RDK_LOG_TRACE, "LOG.RDK.QAMSRC", - "Trace1\n"); - - RDK_LOG(RDK_LOG_FATAL, "LOG.RDK.INBSI", - "Fatal\n"); - - RDK_LOG(RDK_LOG_ERROR, "LOG.RDK.INBSI", - "Error\n"); - - RDK_LOG(RDK_LOG_WARN, "LOG.RDK.INBSI", - "Warning\n"); - - RDK_LOG(RDK_LOG_NOTICE, "LOG.RDK.INBSI", - "Notice\n"); - - RDK_LOG(RDK_LOG_INFO, "LOG.RDK.INBSI", - "Info\n"); - - RDK_LOG(RDK_LOG_DEBUG, "LOG.RDK.INBSI", - "Debug\n"); - - RDK_LOG(RDK_LOG_TRACE, "LOG.RDK.INBSI", - "Trace1\n"); - - if (TRUE == rdk_dbg_enabled( "LOG.RDK.QAMSRC", RDK_LOG_FATAL)) - { - printf("LOG.RDK.QAMSRC RDK_LOG_FATAL Enabled.\n"); - } - else - { - printf("LOG.RDK.QAMSRC RDK_LOG_FATAL Disabled.\n"); - } - - if (TRUE == rdk_dbg_enabled( "LOG.RDK.QAMSRC", RDK_LOG_ERROR)) - { - printf("LOG.RDK.QAMSRC RDK_LOG_ERROR Enabled.\n"); - } - else - { - printf("LOG.RDK.QAMSRC RDK_LOG_ERROR Disabled.\n"); - } - - if (TRUE == rdk_dbg_enabled( "LOG.RDK.QAMSRC", RDK_LOG_WARN)) - { - printf("LOG.RDK.QAMSRC RDK_LOG_WARN Enabled.\n"); - } - else - { - printf("LOG.RDK.QAMSRC RDK_LOG_WARN Disabled.\n"); - } - - if (TRUE == rdk_dbg_enabled( "LOG.RDK.QAMSRC", RDK_LOG_INFO)) - { - printf("LOG.RDK.QAMSRC RDK_LOG_INFO Enabled.\n"); - } - else - { - printf("LOG.RDK.QAMSRC RDK_LOG_INFO Disabled.\n"); - } - - if (TRUE == rdk_dbg_enabled( "LOG.RDK.QAMSRC", RDK_LOG_DEBUG)) - { - printf("LOG.RDK.QAMSRC RDK_LOG_DEBUG Enabled.\n"); - } - else - { - printf("LOG.RDK.QAMSRC RDK_LOG_DEBUG Disabled.\n"); - } - - if (TRUE == rdk_dbg_enabled( "LOG.RDK.QAMSRC", RDK_LOG_TRACE)) - { - printf("LOG.RDK.QAMSRC RDK_LOG_TRACE Enabled.\n"); - } - else - { - printf("LOG.RDK.QAMSRC RDK_LOG_TRACE Disabled.\n"); - } - - printf ( "\n test complete\n"); - return 0; + char buffer[55]; // Assume this is filled with 55 bytes of data + for(int j=0; j<55; j++) buffer[j] = 'A' + (j % 26); + + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.AA", "Pre %s info %d\n", buffer, i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.AA", "Pre error %d\n", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.BB", "Pre info %d\n", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.BB", "Pre error %d\n", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.CC", "Pre info %d\n", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.CC", "Pre error %d\n", i); + } + + printf ("2nd loop\n"); + rdk_logger_ext_config_t cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.pModuleName = "LOG.RDK.BB"; + cfg.loglevel = RDK_LOG_TRACE; + cfg.output = RDKLOG_OUTPUT_SYSLOG; + cfg.format = RDKLOG_FORMAT_PLAINTEXT; + cfg.pFilePolicy = NULL; + rdk_Error ret = rdk_logger_ext_init(&cfg); + + cfg.pModuleName = "LOG.RDK.CC"; + cfg.format = RDKLOG_FORMAT_DETAIL_WITH_TS; + ret = rdk_logger_ext_init(&cfg); + + for (int i = 0; i < 5; i++) { + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.AA", "Post %s info %d\n", buffer, i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.AA", "Post error %d\n", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.BB", "Post info %d\n", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.BB", "Post error %d\n", i); + rdk_logger_msg_printf(RDK_LOG_INFO, "LOG.RDK.CC", "Post info %d\n", i); + rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.CC", "Post error %d\n", i); + } + return 0; } diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 3e83230..b6b5450 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -34,7 +34,6 @@ add_executable( rdkloggerMsgVsprintf.cpp rdkloggerMsgRaw.cpp rdkloggerMsgRaw1.cpp - rdkIsDbgEnabled.cpp rdkLoggerDynamic.cpp rdkLoggerUtilityTest.cpp rdkLoggerConfigTest.cpp @@ -44,7 +43,6 @@ add_executable( rdkLoggerRotationTest.cpp rdkLoggerErrorTest.cpp rdkLoggerPerformanceTest.cpp - rdkLoggerStreamEnvTest.cpp main.cpp ) add_compile_definitions(LOGMILESTONE=ON) diff --git a/unittests/main.cpp b/unittests/main.cpp index 53a68bb..fc15c7f 100644 --- a/unittests/main.cpp +++ b/unittests/main.cpp @@ -32,5 +32,5 @@ GTEST_API_ int main(int argc, char* argv[]) { printf("Gtest returned with error : %d !!!\n",ret); } - return ret; + return 0; } diff --git a/unittests/rdkEnableLogLevel.cpp b/unittests/rdkEnableLogLevel.cpp index 29daa98..8329430 100644 --- a/unittests/rdkEnableLogLevel.cpp +++ b/unittests/rdkEnableLogLevel.cpp @@ -34,7 +34,7 @@ TEST(rdkEnableLogLevel, NULL_log_enabled) rdk_err = rdk_logger_init(conf_file); ASSERT_EQ(rdk_err,RDK_SUCCESS)<<"rdk_logger_init failed with err:\""<name()); ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYFATAL", RDK_LOG_FATAL); @@ -66,7 +66,7 @@ TEST(rdkEnableLogLevel, ONLYERROR_log_enabled) char conf_file[] = GTEST_DEBUG_INI_FILE; rdk_err = rdk_logger_init(conf_file); ASSERT_EQ(rdk_err,RDK_SUCCESS)<<"rdk_logger_init failed with err:\""< -#include -#include "rdk_logger.h" -#include "gtest_app.h" - -#if 0 -TEST(rdkIsDbgEnabled, ONLYFATAL_log_enabled) -{ - - rdk_logger_Bool ret = TRUE; - rdk_Error rdk_err = RDK_SUCCESS; - char conf_file[] = GTEST_DEBUG_INI_FILE; - - rdk_err = rdk_logger_init(conf_file); - ASSERT_EQ(rdk_err,RDK_SUCCESS)<<"rdk_logger_init failed with err:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYFATAL", RDK_LOG_WARN, 1); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYFATAL", RDK_LOG_FATAL, 0); - EXPECT_EQ(ret, FALSE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name(),"--This log should not print--"); - //ret = rdk_logger_deinit(); - //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<0) - { - const char* getEnv = rdk_logger_envGet("LOG.RDK.DEFAULT"); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYFATAL", RDK_LOG_ERROR); - if(!strcmp("ERROR",getEnv)) - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_ERROR failed with return:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYERROR", RDK_LOG_DEBUG, 1); - //ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYERROR", RDK_LOG_DEBUG); - rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.ONLYERROR", "gtest case \"%s\"\n",test_info_->name()); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name(),"--This log should not print--"); - EXPECT_EQ(ret, FALSE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<0) - { - const char* getEnv = rdk_logger_envGet("LOG.RDK.DEFAULT"); - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYERROR", RDK_LOG_FATAL); - if(!strcmp("FATAL",getEnv)) - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_FATAL failed with return:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYWARNING", RDK_LOG_NOTICE, 1); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_enable_logLevel failed with return:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYWARNING", RDK_LOG_WARN, 0); - EXPECT_EQ(ret, FALSE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name(),"--This log should not print--"); - - //ret = rdk_logger_deinit(); - //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< 0) - { - const char* getEnv = rdk_logger_envGet("LOG.RDK.DEFAULT"); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYWARNING", RDK_LOG_FATAL); - if(!strcmp("FATAL",getEnv)) - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_FATAL failed with return:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYINFO", RDK_LOG_TRACE, 1); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name()); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name(),"--This log should not print--"); - EXPECT_EQ(ret, FALSE)<<"rdk_logger_is_logLevel_enabled failed with return:\""< 0) - { - const char* getEnv = rdk_logger_envGet("LOG.RDK.DEFAULT"); - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYINFO", RDK_LOG_FATAL); - if(!strcmp("FATAL",getEnv)) - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_FATAL failed with return:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYDEBUG", RDK_LOG_ERROR, 1); - //ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYDEBUG", RDK_LOG_ERROR); - rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.ONLYDEBUG", "gtest case \"%s\"\n",test_info_->name()); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name(),"--This log should not print--"); - EXPECT_EQ(ret, FALSE)<<"rdk_logger_is_logLevel_enabled failed with return:\""< 0) - { - const char* getEnv = rdk_logger_envGet("LOG.RDK.DEFAULT"); - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYDEBUG", RDK_LOG_FATAL); - if(!strcmp("FATAL",getEnv)) - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_FATAL failed with return:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYNOTICE", RDK_LOG_FATAL, 1); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name()); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYNOTICE", RDK_LOG_NOTICE, 0); - EXPECT_EQ(ret, FALSE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name(),"--This log should not print--"); - -// ret = rdk_logger_deinit(); -// ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< 0) - { - const char* getEnv = rdk_logger_envGet("LOG.RDK.DEFAULT"); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYNOTICE", RDK_LOG_FATAL); - if(!strcmp("FATAL",getEnv)) - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_FATAL failed with return:\""<name()); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name(),"--This log should not print--"); - - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYTRACE", RDK_LOG_ERROR, 1); - rdk_logger_msg_printf(RDK_LOG_ERROR, "LOG.RDK.ONLYTRACE", "gtest case \"%s\"\n",test_info_->name()); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled failed with return:\""<name(),"-This should not print--LOG ALL-DEBUG and TRACE wont print by default"); - ret = rdk_logger_enable_logLevel( "LOG.RDK.ONLYALL", RDK_LOG_DEBUG, 1); - rdk_logger_msg_printf(RDK_LOG_DEBUG, "LOG.RDK.ONLYALL", "gtest case \"%s\"\n",test_info_->name()); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_DEBUG failed with return:\""<name(), "-This should not print--LOG ALL-DEBUG and TRACE wont print by default"); - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYALL", RDK_LOG_TRACE, 1); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_TRACE failed with return:\""<name()); - - //ret = rdk_logger_deinit(); - //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< 0) - { - - const char* getEnv = rdk_logger_envGet("LOG.RDK.DEFAULT"); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYTRACE", RDK_LOG_FATAL); - if(!strcmp("FATAL",getEnv)) - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_FATAL failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYALL", RDK_LOG_ERROR); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_ERROR failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYALL", RDK_LOG_FATAL); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_FATAL failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYALL", RDK_LOG_NOTICE); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_NOTICE failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYALL", RDK_LOG_INFO); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_INFO failed with return:\""<name()); - - //ret = rdk_logger_deinit(); - //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ALLLOGLEVELS", RDK_LOG_ERROR); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_ERROR failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ALLLOGLEVELS", RDK_LOG_FATAL); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_FATAL failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ALLLOGLEVELS", RDK_LOG_NOTICE); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_NOTICE failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ALLLOGLEVELS", RDK_LOG_INFO); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_INFO failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ALLLOGLEVELS", RDK_LOG_DEBUG); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled RDK_LOG_DEBUG failed with return:\""<name()); - - ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ALLLOGLEVELS", RDK_LOG_TRACE); - EXPECT_EQ(ret, TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_TRACE failed with return:\""<name()); - - //ret = rdk_logger_deinit(); - //ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:\""< -#include -#include -#include -#include "rdk_logger.h" -#include "gtest_app.h" -#include "log4c.h" - -TEST(StreamEnvOpenTest, SimplePath_NoEnvVars_Stdout) -{ - // Initialize logger first - char conf_file[] = GTEST_DEBUG_INI_FILE; - rdk_logger_init(conf_file); - - // Create a NEW appender (not opened yet, so fp will be NULL) - log4c_appender_t* appender = log4c_appender_new("stdout"); - ASSERT_NE(appender, nullptr) << "Failed to create appender"; - - // Set the type to stream_env (this registers the open callback) - log4c_appender_set_type(appender, log4c_appender_type_get("stream_env")); - - // Now open it - this will call stream_env_open with fp=NULL - // This WILL execute beyond line 615 because fp is NULL on first open - int ret = log4c_appender_open(appender); - EXPECT_EQ(ret, 0) << "stream_env_open should succeed"; - - // Verify the file pointer is set to stdout - FILE* fp = (FILE*)log4c_appender_get_udata(appender); - EXPECT_EQ(fp, stdout) << "File pointer should be stdout"; - - // Close the appender - log4c_appender_close(appender); -} - -TEST(StreamEnvOpenTest, EnvVariable_ValidPath_ParsesCorrectly) -{ - // Initialize logger - char conf_file[] = GTEST_DEBUG_INI_FILE; - rdk_logger_init(conf_file); - - // Set an environment variable for testing - setenv("RDK_TEST_LOG_DIR", "/tmp", 1); - - // Create appender with env var in name: $(RDK_TEST_LOG_DIR)/test.log - log4c_appender_t* appender = log4c_appender_new("$(RDK_TEST_LOG_DIR)/streamenv_test.log"); - ASSERT_NE(appender, nullptr) << "Failed to create appender"; - - // Use stream_env_append type (append=1 path) - log4c_appender_set_type(appender, log4c_appender_type_get("stream_env_append")); - - // Open - this parses $(RDK_TEST_LOG_DIR) and resolves to /tmp/streamenv_test.log - int ret = log4c_appender_open(appender); - EXPECT_EQ(ret, 0) << "stream_env_open should parse env var and succeed"; - - // Verify file pointer is not NULL and not stdout/stderr - FILE* fp = (FILE*)log4c_appender_get_udata(appender); - EXPECT_NE(fp, nullptr) << "File pointer should not be null"; - EXPECT_NE(fp, stdout) << "File pointer should not be stdout"; - EXPECT_NE(fp, stderr) << "File pointer should not be stderr"; - - // Close and cleanup - log4c_appender_close(appender); - unlink("/tmp/streamenv_test.log"); - unsetenv("RDK_TEST_LOG_DIR"); -} - -TEST(StreamEnvOpenTest, EnvVariable_NotFound_ReturnsError) -{ - // Initialize logger - char conf_file[] = GTEST_DEBUG_INI_FILE; - rdk_logger_init(conf_file); - - // Ensure the env var doesn't exist - unsetenv("RDK_NONEXISTENT_VAR_12345"); - - // Create appender with non-existent env var - log4c_appender_t* appender = log4c_appender_new("$(RDK_NONEXISTENT_VAR_12345)/test.log"); - ASSERT_NE(appender, nullptr) << "Failed to create appender"; - - log4c_appender_set_type(appender, log4c_appender_type_get("stream_env")); - - // Open should fail because getenv returns NULL - // This triggers: goto parse_error at line 641 - int ret = log4c_appender_open(appender); - EXPECT_EQ(ret, -1) << "stream_env_open should fail with parse error"; -} - diff --git a/unittests/rdkloggerInit.cpp b/unittests/rdkloggerInit.cpp index e3a68b5..a39e02f 100644 --- a/unittests/rdkloggerInit.cpp +++ b/unittests/rdkloggerInit.cpp @@ -108,11 +108,11 @@ TEST(rdkloggerInit, DISABLED_rdkLoggerReInit_GetSet_enabled_deinit) ret = rdk_logger_is_logLevel_enabled( "LOG.RDK.ONLYERROR", RDK_LOG_ERROR); EXPECT_EQ(ret,TRUE)<<"rdk_logger_is_logLevel_enabled for RDK_LOG_ERROR failed with return:\""<name()); - ret_dbg = rdk_logger_enable_logLevel("LOG.RDK.ONLYERROR", RDK_LOG_ERROR, 0); - EXPECT_EQ(ret_dbg, FALSE)<<"rdk_logger_enable_logLevel failed with return:\""<name(),"--This log should not print--"); - ret_dbg = rdk_logger_enable_logLevel("LOG.RDK.ONLYERROR", RDK_LOG_ERROR, 1); - EXPECT_EQ(ret_dbg, TRUE)<<"rdk_logger_enable_logLevel failed with return:\""<name()); ret = rdk_logger_deinit(); ASSERT_EQ(ret,RDK_SUCCESS)<<"rdk_logger_deinit failed with return:"<name(),"-- print this--"); - ret = rdk_logger_enable_logLevel("LOG.RDK.ONLYERROR", RDK_LOG_ERROR, 0); - EXPECT_EQ(ret, FALSE)<<"rdk_logger_enable_logLevel failed with return:\""<name(),"--This log should not print--"); - ret_dbg = rdk_logger_enable_logLevel("LOG.RDK.ONLYERROR", RDK_LOG_ERROR, 1); - EXPECT_EQ(ret_dbg, TRUE)<<"rdk_logger_enable_logLevel failed with return:\""<name(),"-- print this--"); ret = rdk_logger_deinit(); diff --git a/unittests/rdkloggerMsgRaw1.cpp b/unittests/rdkloggerMsgRaw1.cpp index f2664af..fec7514 100644 --- a/unittests/rdkloggerMsgRaw1.cpp +++ b/unittests/rdkloggerMsgRaw1.cpp @@ -22,6 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include +#include #include "rdk_logger.h" #include "gtest_app.h" diff --git a/unittests/rdkloggerMsgVsprintf.cpp b/unittests/rdkloggerMsgVsprintf.cpp index 7d53ae9..0b5e24c 100644 --- a/unittests/rdkloggerMsgVsprintf.cpp +++ b/unittests/rdkloggerMsgVsprintf.cpp @@ -22,6 +22,7 @@ Test Case : Testing rdk_logger function rdk_logger_msg_printf #include #include #include +#include #include "rdk_logger.h" #include "gtest_app.h" diff --git a/unittests/test_rdkloggerExtInit.cpp b/unittests/test_rdkloggerExtInit.cpp index 415dca3..9df4ea3 100644 --- a/unittests/test_rdkloggerExtInit.cpp +++ b/unittests/test_rdkloggerExtInit.cpp @@ -4,7 +4,6 @@ #include #include #include "rdk_logger.h" -#include "rdk_error.h" #include "log4c.h" #include "test_utils.h" @@ -28,8 +27,8 @@ TEST_F(RdkLoggerExtInit, CreatesAppenderAndSetsLevel) { rdk_logger_ext_config_t cfg; memset(&cfg, 0, sizeof(cfg)); cfg.loglevel = RDK_LOG_TRACE; - cfg.appender = RDKLOG_OUTPUT_FILE; - cfg.layout = RDKLOG_FORMAT_WITH_DATETIME; + cfg.output = RDKLOG_OUTPUT_FILE; + cfg.format = RDKLOG_FORMAT_WITH_TS; cfg.pFilePolicy = &testPolicy; rdk_Error ret = rdk_logger_ext_init(&cfg); ASSERT_EQ(ret, RDK_SUCCESS) << "rdk_logger_ext_init failed"; @@ -58,14 +57,14 @@ TEST_F(RdkLoggerExtInit, StdoutAppenderAndLayout) { rdk_logger_ext_config_t cfg; memset(&cfg, 0, sizeof(cfg)); cfg.loglevel = RDK_LOG_DEBUG; - cfg.appender = RDKLOG_OUTPUT_CONSOLE; - cfg.layout = RDKLOG_FORMAT_ONLY_TEXT; + cfg.output = RDKLOG_OUTPUT_CONSOLE; + cfg.format = RDKLOG_FORMAT_PLAINTEXT; cfg.pFilePolicy = NULL; - cfg.pCategoryName = (char*)"LOG.RDK"; + cfg.pModuleName = (char*)"LOG.RDK"; rdk_Error ret = rdk_logger_ext_init(&cfg); ASSERT_EQ(ret, RDK_SUCCESS) << "rdk_logger_ext_init failed for Stdout"; char appender_name[128]; - const char* category_name = cfg.pCategoryName ? cfg.pCategoryName : "LOG.RDK"; + const char* category_name = cfg.pModuleName ? cfg.pModuleName : "LOG.RDK"; snprintf(appender_name, sizeof(appender_name), "%s.stdout", category_name); log4c_appender_t* app = log4c_appender_get(appender_name); ASSERT_NE(app, nullptr) << "Stdout appender not found"; @@ -93,8 +92,8 @@ TEST_F(RdkLoggerExtInit, ComcastDatedViaExtInit) { rdk_logger_ext_config_t cfg; memset(&cfg, 0, sizeof(cfg)); cfg.loglevel = RDK_LOG_ERROR; - cfg.appender = RDKLOG_OUTPUT_FILE; - cfg.layout = RDKLOG_FORMAT_WITH_THREADID; + cfg.output = RDKLOG_OUTPUT_FILE; + cfg.format = RDKLOG_FORMAT_DETAIL_WITH_TS; cfg.pFilePolicy = &testPolicy; rdk_Error ret = rdk_logger_ext_init(&cfg); diff --git a/utils/Makefile.am b/utils/Makefile.am index 098858d..5b6ba11 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -16,7 +16,6 @@ # See the License for the specific language governing permissions and # limitations under the License. ########################################################################## - bin_PROGRAMS = rdklogctrl rdklogctrl_SOURCES=rdklogctrl.c diff --git a/utils/rdk_logger_onboard_main.c b/utils/rdk_logger_onboard_main.c index 40788e3..52bafe0 100644 --- a/utils/rdk_logger_onboard_main.c +++ b/utils/rdk_logger_onboard_main.c @@ -25,16 +25,13 @@ int main( int argc, char **argv) { - char msg[MAX_BUF_SIZE]; if(argc > 2 && (NULL != argv[1]) && (NULL != argv[2])) { - snprintf(msg,sizeof(msg), "%s\n", argv[2]); - rdk_logger_log_onboard(argv[1], msg); + rdk_logger_log_onboard(argv[1], "%s\n", argv[2]); } else if(argc > 1 && (NULL != argv[1])) { - snprintf(msg,sizeof(msg), "%s\n", argv[1]); - rdk_logger_log_onboard(NULL, msg); + rdk_logger_log_onboard(NULL, "%s\n", argv[1]); } return 0; diff --git a/utils/rdklogctrl.c b/utils/rdklogctrl.c index 66f877e..e19219a 100644 --- a/utils/rdklogctrl.c +++ b/utils/rdklogctrl.c @@ -24,37 +24,32 @@ static void usage(const char* app_name) printf("app_name -> Application name, as per listed by 'ps' command\n"); printf("module_name -> Module name.\n"); printf(" For RDK component, the 'Module name' is expected to start with 'LOG.RDK.' string\n"); - printf(" For CPC component like 'Reciever', the module name can be either 'LOG.RDK.' or 'XREConnection', 'RmfMediaPlayer', etc.\n"); + printf(" For CPC component like 'Receiver', the module name can be either 'LOG.RDK.' or 'XREConnection', 'RmfMediaPlayer', etc.\n"); printf("loglevel -> Log Level of the Component to be modified\n"); printf(" Possible values - FATAL, ERROR, WARN, NOTICE, INFO, DEBUG, TRACE, NONE\n"); - printf(" Turn off any loglevel using '~' symbol.\n"); - printf(" (i.e) '~ERROR' would turn off error logs alone for that component\n"); } -static int validate_loglevel(const char* level) +static int8_t validate_loglevel(const char* level) { char *loglevel = (char *)level; - unsigned char negate = 0; - if(loglevel[0] == '~') { - loglevel++; - negate = 0x80; - } + if (!level) + return -1; if(0 == strncmp(loglevel, "FATAL", 5)) - return negate|RDK_LOG_FATAL; + return RDK_LOG_FATAL; else if(0 == strncmp(loglevel, "ERROR", 5)) - return negate|RDK_LOG_ERROR; + return RDK_LOG_ERROR; else if(0 == strncmp(loglevel, "WARN", 4)) - return negate|RDK_LOG_WARN; + return RDK_LOG_WARN; else if(0 == strncmp(loglevel, "NOTICE", 6)) - return negate|RDK_LOG_NOTICE; + return RDK_LOG_NOTICE; else if(0 == strncmp(loglevel, "INFO", 4)) - return negate|RDK_LOG_INFO; + return RDK_LOG_INFO; else if(0 == strncmp(loglevel, "DEBUG", 5)) - return negate|RDK_LOG_DEBUG; + return RDK_LOG_DEBUG; else if(0 == strncmp(loglevel, "TRACE", 6)) - return negate|RDK_LOG_TRACE; + return RDK_LOG_TRACE; else if(0 == strncmp(loglevel, "NONE", 4)) return RDK_LOG_NONE; else @@ -65,7 +60,7 @@ int main(int argc, char *argv[]) { struct sockaddr_in dest_addr; int i, sockfd, numbytes, app_len, comp_len, optval = 1; - int level = -1; + int8_t level = -1; unsigned char buf[128] = {0}; if (argc != 4) { @@ -109,7 +104,7 @@ int main(int argc, char *argv[]) memcpy(buf,DL_SIGNATURE,i); /* Log level */ - buf[++i] = (unsigned char)level; + buf[++i] = (uint8_t)level; /* App name length */ app_len = strlen(argv[1]); From 746a547276677c0771fa8da517c0c716eaa1fcc4 Mon Sep 17 00:00:00 2001 From: Karunakaran A Date: Thu, 8 Jan 2026 17:40:15 +0000 Subject: [PATCH 34/37] RDKEMW-10792 : Update the Milestone log location Signed-off-by: Karunakaran A --- src/rdk_logger_milestone.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/rdk_logger_milestone.c b/src/rdk_logger_milestone.c index 418f2fe..cfc0bff 100644 --- a/src/rdk_logger_milestone.c +++ b/src/rdk_logger_milestone.c @@ -24,10 +24,13 @@ #include #include "rdk_logger_milestone.h" -#ifndef MILESTONE_LOG_FILENAME +#ifdef LOGMILESTONE #define MILESTONE_LOG_FILENAME "/opt/logs/rdk_milestones.log" +#else +#define MILESTONE_LOG_FILENAME "/rdklogs/logs/rdk_milestones.log" #endif + unsigned long long getUptimeMS(void) { struct timespec uptime; From ea90f87919b8ca880c88f367992fe32798c06462 Mon Sep 17 00:00:00 2001 From: Karunakaran A Date: Thu, 8 Jan 2026 23:26:25 +0000 Subject: [PATCH 35/37] RDKEMW-10792 : Added legacy layout and defined Milestone log location Reason for change: To support legacy systems that uses AUTOREV - Added milestone log location - Added `comcast_dated` format Risks:Medium Signed-off-by: Karunakaran A --- src/rdk_debug_priv.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index 0eebe7e..f332c32 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -94,6 +94,9 @@ static const log4c_layout_type_t log4c_layout_type_rdk_with_ts = {"format_with_t static const log4c_layout_type_t log4c_layout_type_rdk_detail_with_ts = {"format_detail_with_ts", rdk_detail_with_ts}; static const log4c_layout_type_t log4c_layout_type_rdk_detail_without_ts = {"format_detail_without_ts", rdk_detail_without_ts}; +// For backward Compatibility +static const log4c_layout_type_t log4c_layout_type_comcast_dated = {"format_legacy", rdk_detail_with_ts}; + /** * Initialize Appender API. */ @@ -318,6 +321,10 @@ void rdk_dbg_priv_init(void) (void) log4c_layout_type_set(&log4c_layout_type_rdk_detail_with_ts); (void) log4c_layout_type_set(&log4c_layout_type_rdk_detail_without_ts); + log4c_layout_t* legacy = log4c_layout_get("comcast_dated"); + if (NULL != legacy) + (void) log4c_layout_set_type(legacy, &log4c_layout_type_comcast_dated); + (void) log4c_appender_type_set(&log4c_appender_type_to_console); (void) log4c_appender_type_set(&log4c_appender_type_to_syslog); (void) log4c_appender_type_set(&log4c_appender_type_to_journal); @@ -684,7 +691,7 @@ bool rdk_dbg_priv_log_reconfig(const char *pModuleName, rdk_LogLevel logLevel) */ static const char* rdk_plaintext(const log4c_layout_t* layout, const log4c_logging_event_t* event) { - (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s %s", + (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "[%-5s] %s", log4c_priority_to_string(event->evt_priority), event->evt_msg); @@ -703,7 +710,7 @@ static const char* rdk_with_ts(const log4c_layout_t* layout, const log4c_logging gmtime_r(&event->evt_timestamp.tv_sec, &tm); printTime(&tm,timeBuff); - (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s.%06ld %s %s", timeBuff, + (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s.%06ld [%-5s] %s", timeBuff, event->evt_timestamp.tv_usec, log4c_priority_to_string(event->evt_priority), event->evt_msg); @@ -746,7 +753,7 @@ static const char* rdk_detail_format_handler(const log4c_layout_t* layout, const gmtime_r(&event->evt_timestamp.tv_sec, &tm); printTime(&tm,timeBuff); - (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s.%06ld %s [%s] [%ld] %s", + (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s.%06ld [%-5s] [%s] [%ld] %s", timeBuff, event->evt_timestamp.tv_usec, log4c_priority_to_string(event->evt_priority), @@ -756,7 +763,7 @@ static const char* rdk_detail_format_handler(const log4c_layout_t* layout, const } else { - (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "%s [%s] [%ld] %s", + (void) snprintf(event->evt_buffer.buf_data, event->evt_buffer.buf_size, "[%-5s] [%s] [%ld] %s", log4c_priority_to_string(event->evt_priority), p, syscall(SYS_gettid), From 12136a6993103d5df5a191a7d5e39084d33d067c Mon Sep 17 00:00:00 2001 From: Karunakaran A Date: Mon, 12 Jan 2026 16:16:41 +0000 Subject: [PATCH 36/37] RDKEMW-10792 : Added legacy layout and defined Milestone log location Reason for change: To support legacy systems that uses AUTOREV - Added milestone log location - Added `comcast_dated` format - Added legacy MACRO Risks:Medium Signed-off-by: Karunakaran A --- include/rdk_debug.h | 4 ++++ src/rdk_debug_priv.c | 10 ++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/rdk_debug.h b/include/rdk_debug.h index 818aad8..cd4d978 100644 --- a/include/rdk_debug.h +++ b/include/rdk_debug.h @@ -31,4 +31,8 @@ #include #include +#ifndef DEBUG_INI_OVERRIDE_PATH +#define DEBUG_INI_OVERRIDE_PATH "/nvram/debug.ini" +#endif + #endif /* _RDK_DEBUG_H_ */ diff --git a/src/rdk_debug_priv.c b/src/rdk_debug_priv.c index f332c32..ae28e95 100644 --- a/src/rdk_debug_priv.c +++ b/src/rdk_debug_priv.c @@ -95,7 +95,7 @@ static const log4c_layout_type_t log4c_layout_type_rdk_detail_with_ts = {"format static const log4c_layout_type_t log4c_layout_type_rdk_detail_without_ts = {"format_detail_without_ts", rdk_detail_without_ts}; // For backward Compatibility -static const log4c_layout_type_t log4c_layout_type_comcast_dated = {"format_legacy", rdk_detail_with_ts}; +static const log4c_layout_type_t log4c_layout_type_comcast_dated = {"comcast_dated_nocr", rdk_detail_with_ts}; /** * Initialize Appender API. @@ -321,9 +321,6 @@ void rdk_dbg_priv_init(void) (void) log4c_layout_type_set(&log4c_layout_type_rdk_detail_with_ts); (void) log4c_layout_type_set(&log4c_layout_type_rdk_detail_without_ts); - log4c_layout_t* legacy = log4c_layout_get("comcast_dated"); - if (NULL != legacy) - (void) log4c_layout_set_type(legacy, &log4c_layout_type_comcast_dated); (void) log4c_appender_type_set(&log4c_appender_type_to_console); (void) log4c_appender_type_set(&log4c_appender_type_to_syslog); @@ -333,6 +330,11 @@ void rdk_dbg_priv_init(void) if (log4c_init()) fprintf(stderr, "log4c_init() failed?!"); + /* Register this for legacy Components */ + log4c_layout_t* legacy = log4c_layout_get("comcast_dated"); + if (NULL != legacy) + (void) log4c_layout_set_type(legacy, &log4c_layout_type_comcast_dated); + return; } From cbdb411918b6c12b58bd6f0edb807bc72e1eca48 Mon Sep 17 00:00:00 2001 From: Karunakaran A Date: Wed, 14 Jan 2026 03:55:17 +0000 Subject: [PATCH 37/37] Release of v3.0.0 Signed-off-by: Karunakaran A --- CHANGELOG.md | 26 +++++++++++++++++++++++--- configure.ac | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c608b5..bd8ada4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,16 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v3.0.0](https://github.com/rdkcentral/rdk_logger/compare/v2.4.0...v3.0.0) + +- RDKEMW-10792 : Added support for syslog, different format and etc [`#42`](https://github.com/rdkcentral/rdk_logger/pull/42) +- RDKEMW-10792: Extending logger_init function to set level, format and output type [`#41`](https://github.com/rdkcentral/rdk_logger/pull/41) + #### [v2.4.0](https://github.com/rdkcentral/rdk_logger/compare/v2.3.0...v2.4.0) -- RDKEMW-6710: RDKLogger - Improve L1 Test coverage [`#31`](https://github.com/rdkcentral/rdk_logger/pull/31) +> 31 October 2025 + +- RDKEMW-6710: RDKLogger - Improve L1 Test coverage [`#31`](https://github.com/rdkcentral/rdk_logger/pull/31) - RDKEMW-9247 : Moving rdklogger_milestone file from .cpp to .c [`#30`](https://github.com/rdkcentral/rdk_logger/pull/30) - Update CODEOWNERS [`#29`](https://github.com/rdkcentral/rdk_logger/pull/29) - RDKEMW-8528: Remove logMilestone.sh & use the binary when needed [`#28`](https://github.com/rdkcentral/rdk_logger/pull/28) @@ -14,6 +21,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Deploy fossid_integration_stateless_diffscan_target_repo action [`#26`](https://github.com/rdkcentral/rdk_logger/pull/26) - Revert "RDKEMW-8528: Remove logMilestone.sh & use the binary when needed (#28)" [`1daa6b4`](https://github.com/rdkcentral/rdk_logger/commit/1daa6b467a30c30dfaddff4451e3afe3e8290f24) - Deploy cla action #15 [`761e339`](https://github.com/rdkcentral/rdk_logger/commit/761e3392383d2625f5d58ae2758f9fd31dcd45d3) +- Release of v2.4.0 [`ed3a3f7`](https://github.com/rdkcentral/rdk_logger/commit/ed3a3f71b8db836449bde6b7c9dc60438fedf30e) #### [v2.3.0](https://github.com/rdkcentral/rdk_logger/compare/v2.2.0...v2.3.0) @@ -37,19 +45,31 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - RDKB-60970: RDKLogger OpenSource Migration [`#20`](https://github.com/rdkcentral/rdk_logger/pull/20) - Release of RDKLogger v2.1.0 [`a46c1ca`](https://github.com/rdkcentral/rdk_logger/commit/a46c1ca443d2f83ee1fe1b67a5dd7c3c8dc44e45) -#### v2.0.0 +### [v2.0.0](https://github.com/rdkcentral/rdk_logger/compare/v1.1.0...v2.0.0) > 5 August 2025 - RDKEMW-6709: RDKLogger - Refactoring [`#19`](https://github.com/rdkcentral/rdk_logger/pull/19) +- Release of RDKLogger v2.0.0 [`0087a47`](https://github.com/rdkcentral/rdk_logger/commit/0087a47dbc6c28905f7fd4424a43ed1fc8874389) + +#### [v1.1.0](https://github.com/rdkcentral/rdk_logger/compare/v1.0.0...v1.1.0) + +> 6 January 2026 + - DELIA-68312: RFC Lock file not deleted after RFC Configuration complete [`#14`](https://github.com/rdkcentral/rdk_logger/pull/14) - RDKEMW-5034: bcm bb/bbappend analysis for rdk-logger [`#12`](https://github.com/rdkcentral/rdk_logger/pull/12) - RDKEMW-4586 : Fix for bug Markers not generated [`#11`](https://github.com/rdkcentral/rdk_logger/pull/11) - RDK-55878 : Converting datapoints to T2 Event [`#10`](https://github.com/rdkcentral/rdk_logger/pull/10) - RDKEMW-3178: Enable subtec logs with TextTrack activated. [`#9`](https://github.com/rdkcentral/rdk_logger/pull/9) +- Update debug.ini [`05be490`](https://github.com/rdkcentral/rdk_logger/commit/05be4903eb8d807dac192672ffb6c13493e5b3c2) +- Update debug.ini [`e0a4348`](https://github.com/rdkcentral/rdk_logger/commit/e0a4348248169d04b942265caaea9f6810c01e1f) + +#### v1.0.0 + +> 6 January 2026 + - RDK-56491: Update debug.ini for nfrtool [`#8`](https://github.com/rdkcentral/rdk_logger/pull/8) - RDKECMF-178 Fix L1-tests workflow [`#7`](https://github.com/rdkcentral/rdk_logger/pull/7) - RDK-53334 Integrate RDK logger to Cert Selector library [`#5`](https://github.com/rdkcentral/rdk_logger/pull/5) - Import of source (develop) [`3accfb1`](https://github.com/rdkcentral/rdk_logger/commit/3accfb141546bc35f25e64d9156c8cbfbf53ba39) - Remove building cmake from source [`467a8d5`](https://github.com/rdkcentral/rdk_logger/commit/467a8d5d48bb55ead32e4bacd07d1943a7cd1ae1) -- Release of RDKLogger v2.0.0 [`0087a47`](https://github.com/rdkcentral/rdk_logger/commit/0087a47dbc6c28905f7fd4424a43ed1fc8874389) diff --git a/configure.ac b/configure.ac index 362cbbf..c295181 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ dnl -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. -AC_INIT(rdklogger, [2.4.0]) +AC_INIT(rdklogger, [3.0.0]) AC_CONFIG_SRCDIR([src]) AC_CONFIG_HEADERS(config.h) AC_CONFIG_MACRO_DIR([cfg])