1 /* 2 * coreMQTT Agent v1.1.0 3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy of 6 * this software and associated documentation files (the "Software"), to deal in 7 * the Software without restriction, including without limitation the rights to 8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 * the Software, and to permit persons to whom the Software is furnished to do so, 10 * subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in all 13 * copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 23 /** 24 * @file logging_stack.h 25 * @brief Reference implementation of Logging stack as a header-only library. 26 */ 27 28 #ifndef LOGGING_STACK_H_ 29 #define LOGGING_STACK_H_ 30 31 /* Include header for logging level macros. */ 32 #include "logging_levels.h" 33 34 /* Standard Include. */ 35 #include <stdio.h> 36 #include <stdint.h> 37 #include <string.h> 38 39 /* The macro definition for LIBRARY_LOG_NAME is for Doxygen 40 * documentation only. This macro is typically defined in only the 41 * <library>_config.h file or the demo_config.h file. */ 42 43 /** 44 * @brief The name of the library or demo to add as metadata in log messages 45 * from the library or demo. 46 * 47 * This metadata aids in identifying the module source of log messages. 48 * The metadata is logged in the format `[ <LIBRARY-NAME> ]` as a prefix to the 49 * log messages. 50 * Refer to #LOG_METADATA_FORMAT for the complete format of the metadata prefix in 51 * log messages. 52 */ 53 #ifdef DOXYGEN 54 #define LIBRARY_LOG_NAME "<LIBRARY_NAME>" 55 #endif 56 57 /* Check if LIBRARY_LOG_NAME macro has been defined. */ 58 #if !defined( LIBRARY_LOG_NAME ) 59 #error "Please define LIBRARY_LOG_NAME for the library." 60 #endif 61 62 /** 63 * @brief Macro to extract only the file name from file path to use for metadata in 64 * log messages. 65 */ 66 #define FILENAME ( strrchr( __FILE__, '/' ) ? strrchr( __FILE__, '/' ) + 1 : __FILE__ ) 67 68 /* Metadata information to prepend to every log message. */ 69 #define LOG_METADATA_FORMAT "[%s] [%s:%d] " /**< @brief Format of metadata prefix in log messages as `[<Logging-Level>] [<Library-Name>] [<File-Name>:<Line-Number>]` */ 70 #define LOG_METADATA_ARGS LIBRARY_LOG_NAME, FILENAME, __LINE__ /**< @brief Arguments into the metadata logging prefix format. */ 71 72 #if !defined( DISABLE_LOGGING ) 73 74 /** 75 * @brief Common macro that maps all the logging interfaces, 76 * (#LogDebug, #LogInfo, #LogWarn, #LogError) to the platform-specific logging 77 * function. 78 * 79 * `printf` from the standard C library is the POSIX platform implementation used 80 * for logging functionality. 81 */ 82 #define SdkLog( string ) printf string 83 #else 84 #define SdkLog( string ) 85 #endif 86 87 /** 88 * Disable definition of logging interface macros when generating doxygen output, 89 * to avoid conflict with documentation of macros at the end of the file. 90 * @cond DOXYGEN_IGNORE 91 */ 92 /* Check that LIBRARY_LOG_LEVEL is defined and has a valid value. */ 93 #if !defined( LIBRARY_LOG_LEVEL ) || \ 94 ( ( LIBRARY_LOG_LEVEL != LOG_NONE ) && \ 95 ( LIBRARY_LOG_LEVEL != LOG_ERROR ) && \ 96 ( LIBRARY_LOG_LEVEL != LOG_WARN ) && \ 97 ( LIBRARY_LOG_LEVEL != LOG_INFO ) && \ 98 ( LIBRARY_LOG_LEVEL != LOG_DEBUG ) \ 99 ) 100 #error "Please define LIBRARY_LOG_LEVEL as either LOG_NONE, LOG_ERROR, LOG_WARN, LOG_INFO, or LOG_DEBUG." 101 #else 102 #if LIBRARY_LOG_LEVEL == LOG_DEBUG 103 /* All log level messages will logged. */ 104 #define LogError( message ) SdkLog( ( "[ERROR] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 105 #define LogWarn( message ) SdkLog( ( "[WARN] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 106 #define LogInfo( message ) SdkLog( ( "[INFO] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 107 #define LogDebug( message ) SdkLog( ( "[DEBUG] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 108 109 #elif LIBRARY_LOG_LEVEL == LOG_INFO 110 /* Only INFO, WARNING and ERROR messages will be logged. */ 111 #define LogError( message ) SdkLog( ( "[ERROR] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 112 #define LogWarn( message ) SdkLog( ( "[WARN] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 113 #define LogInfo( message ) SdkLog( ( "[INFO] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 114 #define LogDebug( message ) 115 116 #elif LIBRARY_LOG_LEVEL == LOG_WARN 117 /* Only WARNING and ERROR messages will be logged.*/ 118 #define LogError( message ) SdkLog( ( "[ERROR] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 119 #define LogWarn( message ) SdkLog( ( "[WARN] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 120 #define LogInfo( message ) 121 #define LogDebug( message ) 122 123 #elif LIBRARY_LOG_LEVEL == LOG_ERROR 124 /* Only ERROR messages will be logged. */ 125 #define LogError( message ) SdkLog( ( "[ERROR] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 126 #define LogWarn( message ) 127 #define LogInfo( message ) 128 #define LogDebug( message ) 129 130 #else /* if LIBRARY_LOG_LEVEL == LOG_ERROR */ 131 132 #define LogError( message ) 133 #define LogWarn( message ) 134 #define LogInfo( message ) 135 #define LogDebug( message ) 136 137 #endif /* if LIBRARY_LOG_LEVEL == LOG_ERROR */ 138 #endif /* if !defined( LIBRARY_LOG_LEVEL ) || ( ( LIBRARY_LOG_LEVEL != LOG_NONE ) && ( LIBRARY_LOG_LEVEL != LOG_ERROR ) && ( LIBRARY_LOG_LEVEL != LOG_WARN ) && ( LIBRARY_LOG_LEVEL != LOG_INFO ) && ( LIBRARY_LOG_LEVEL != LOG_DEBUG ) ) */ 139 /** @endcond */ 140 141 /* Doxygen documentation of logging interface macro definitions for Doxygen. */ 142 #ifdef DOXYGEN 143 144 /** 145 * @brief Definition of logging interface macro that logs messages at the "Debug" 146 * level, when debug level logging is enabled. 147 * 148 * This macro is only enabled for #LOG_DEBUG level configuration in this 149 * logging stack implementation. 150 */ 151 #define LogDebug( message ) SdkLog( ( "[DEBUG] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 152 153 /** 154 * @brief Definition of logging interface macro that logs messages at the "Info" 155 * level, when info level logging is enabled. 156 * 157 * This macro is only enabled for #LOG_DEBUG and #LOG_INFO level configurations 158 * in this logging stack implementation. 159 */ 160 #define LogInfo( message ) SdkLog( ( "[INFO] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 161 162 /** 163 * @brief Definition of logging interface macro that logs messages at the "Warning" 164 * level, when warning level logging is enabled. 165 * 166 * This macro is only enabled for #LOG_DEBUG, #LOG_INFO and #LOG_WARN level 167 * configurations in this logging stack implementation. 168 */ 169 #define LogWarn( message ) SdkLog( ( "[WARN] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 170 171 /** 172 * @brief Definition of logging interface macro that logs messages at the "Error" 173 * level, when error level logging is enabled. 174 * 175 * This macro is only enabled for all logging level configurations 176 * unless except the #LOG_NONE configuration. 177 */ 178 #define LogError( message ) SdkLog( ( "[ERROR] "LOG_METADATA_FORMAT, LOG_METADATA_ARGS ) ); SdkLog( message ); SdkLog( ( "\r\n" ) ) 179 180 #endif /* ifndef DOXYGEN */ 181 182 #endif /* ifndef LOGGING_STACK_H_ */ 183