| /* |
| * |
| * Copyright (c) 2020 Project CHIP Authors |
| * Copyright (c) 2013-2017 Nest Labs, Inc. |
| * |
| * 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 |
| * This file defines macros, constants, and interfaces for a |
| * platform-independent logging interface for the chip SDK. |
| * |
| * chip SDK clients may choose, at compile time, among Android, |
| * C Standard I/O, or external (platform- and integrator-defined) |
| * logging style implementations that will be invoked when any of |
| * the following preprocessor symbols are asserted: |
| * |
| * - #CHIP_ERROR_LOGGING |
| * - #CHIP_PROGRESS_LOGGING |
| * - #CHIP_DETAIL_LOGGING |
| * |
| */ |
| |
| #ifndef CHIPLOGGING_H_ |
| #define CHIPLOGGING_H_ |
| |
| #include <core/CHIPConfig.h> |
| |
| #include <stdarg.h> |
| #include <stdint.h> |
| |
| /** |
| * @namespace chip::Logging |
| * |
| * @brief |
| * This namespace includes all interfaces within chip for shared |
| * logging support. |
| * |
| * The interfaces include macros, constants, and functions for a |
| * platform-independent logging interface for the chip SDK. |
| * |
| * chip SDK clients may choose, at compile time, among Android, |
| * C Standard I/O, or external (platform- and integrator-defined) |
| * logging style implementations that will be invoked when any of |
| * the following preprocessor symbols are asserted: |
| * |
| * - #CHIP_ERROR_LOGGING |
| * - #CHIP_PROGRESS_LOGGING |
| * - #CHIP_DETAIL_LOGGING |
| * |
| */ |
| |
| namespace chip { |
| namespace Logging { |
| |
| /** |
| * @enum LogModule |
| * |
| * @brief |
| * Identifies a logical section of code that is a source of log |
| * messages. |
| * |
| * @note If you add modules or rearrange this list you must update the |
| * ModuleNames tables in ChipLogging.cpp. |
| * |
| */ |
| enum LogModule |
| { |
| kLogModule_NotSpecified = 0, |
| |
| kLogModule_Inet, |
| kLogModule_Ble, |
| kLogModule_MessageLayer, |
| kLogModule_SecurityManager, |
| kLogModule_ExchangeManager, |
| kLogModule_TLV, |
| kLogModule_ASN1, |
| kLogModule_Crypto, |
| kLogModule_Controller, |
| kLogModule_Alarm, |
| kLogModule_BDX, |
| kLogModule_DataManagement, |
| kLogModule_DeviceControl, |
| kLogModule_DeviceDescription, |
| kLogModule_Echo, |
| kLogModule_FabricProvisioning, |
| kLogModule_NetworkProvisioning, |
| kLogModule_ServiceDirectory, |
| kLogModule_ServiceProvisioning, |
| kLogModule_SoftwareUpdate, |
| kLogModule_TokenPairing, |
| kLogModule_TimeService, |
| kLogModule_Heartbeat, |
| kLogModule_chipSystemLayer, |
| kLogModule_EventLogging, |
| kLogModule_Support, |
| kLogModule_chipTool, |
| kLogModule_Zcl, |
| kLogModule_Shell, |
| kLogModule_DeviceLayer, |
| kLogModule_SetupPayload, |
| kLogModule_AppServer, |
| |
| kLogModule_Max |
| }; |
| |
| /** |
| * @enum LogCategory |
| * |
| * @brief |
| * Identifies a category to which an particular error message |
| * belongs. |
| * |
| */ |
| enum LogCategory |
| { |
| /*!< |
| * This log category indicates, when passed to SetLogFilter(), |
| * that no messages should be logged. |
| * |
| */ |
| kLogCategory_None = 0, |
| |
| /*!< |
| * Indicates a category of log message that describes an unexpected |
| * or severe failure. |
| * |
| * This log category indicates that a logged message describes |
| * an unexpected or severe failure in the code. |
| * |
| * It should be used for things such as out-of-resource errors, |
| * internal inconsistencies, API misuse, etc. In general, errors |
| * that are expected to occur as part of normal operation, or |
| * that are largely determined by external factors (e.g. network |
| * errors, user/operator induced errors, etc.) should be logged |
| * as kLogCategory_Progress messages, not as kLogCategory_Error |
| * messages. |
| * |
| */ |
| kLogCategory_Error = 1, |
| |
| /*!< |
| * Indicates a category of log message that describes an event |
| * that marks the start or end of a major activity, or a major |
| * change in the state of the overall system. |
| * |
| * It should be reserved for high-level events. Such messages |
| * should provide the log reader with a good sense of the |
| * overall activity of the system at any point in time, while |
| * being minimally verbose. Where necessary such messages should |
| * include identifiers or other values that can be used to |
| * correlate messages involving a common actor or subject |
| * (e.g. connection ids, request ids, etc.) and/or to identify |
| * types of actions being taken or handled (e.g. message types, |
| * requested resource types, error numbers, etc.). |
| * |
| */ |
| kLogCategory_Progress = 2, |
| |
| /*!< |
| * Indicates a category of log message that describes detailed |
| * information about an event or the state of the system. |
| * |
| * Such messages can be used to provide ancillary information |
| * not suitable for the kLogCategory_Error and |
| * kLogCategory_Progress categories. |
| * |
| */ |
| kLogCategory_Detail = 3, |
| |
| /*!< |
| * Indicates a category of log message that describes information |
| * needed by IE and QA teams for automated testing. |
| * |
| */ |
| kLogCategory_Retain = 4, |
| |
| kLogCategory_Max = kLogCategory_Retain |
| }; |
| |
| extern void LogV(uint8_t module, uint8_t category, const char * msg, va_list args); |
| extern void Log(uint8_t module, uint8_t category, const char * msg, ...); |
| extern uint8_t GetLogFilter(); |
| extern void SetLogFilter(uint8_t category); |
| |
| #ifndef CHIP_ERROR_LOGGING |
| #define CHIP_ERROR_LOGGING 1 |
| #endif |
| |
| #ifndef CHIP_LOG_FILTERING |
| #define CHIP_LOG_FILTERING 1 |
| #endif |
| |
| #if CHIP_ERROR_LOGGING |
| /** |
| * @def ChipLogError(MOD, MSG, ...) |
| * |
| * @brief |
| * Log a chip message for the specified module in the 'Error' |
| * category. |
| * |
| */ |
| #ifndef ChipLogError |
| #define ChipLogError(MOD, MSG, ...) \ |
| chip::Logging::Log(chip::Logging::kLogModule_##MOD, chip::Logging::kLogCategory_Error, MSG, ##__VA_ARGS__) |
| #endif |
| #else |
| #define ChipLogError(MOD, MSG, ...) |
| #endif |
| |
| #ifndef CHIP_PROGRESS_LOGGING |
| #define CHIP_PROGRESS_LOGGING 1 |
| #endif |
| |
| #if CHIP_PROGRESS_LOGGING |
| /** |
| * @def ChipLogProgress(MOD, MSG, ...) |
| * |
| * @brief |
| * Log a chip message for the specified module in the 'Progress' |
| * category. |
| * |
| */ |
| #ifndef ChipLogProgress |
| #define ChipLogProgress(MOD, MSG, ...) \ |
| chip::Logging::Log(chip::Logging::kLogModule_##MOD, chip::Logging::kLogCategory_Progress, MSG, ##__VA_ARGS__) |
| #endif |
| #else |
| #define ChipLogProgress(MOD, MSG, ...) |
| #endif |
| |
| #ifndef CHIP_DETAIL_LOGGING |
| #define CHIP_DETAIL_LOGGING 1 |
| #endif |
| |
| #if CHIP_DETAIL_LOGGING |
| /** |
| * @def ChipLogDetail(MOD, MSG, ...) |
| * |
| * @brief |
| * Log a chip message for the specified module in the 'Detail' |
| * category. |
| * |
| */ |
| #ifndef ChipLogDetail |
| #define ChipLogDetail(MOD, MSG, ...) \ |
| chip::Logging::Log(chip::Logging::kLogModule_##MOD, chip::Logging::kLogCategory_Detail, MSG, ##__VA_ARGS__) |
| #endif |
| #else |
| #define ChipLogDetail(MOD, MSG, ...) |
| #endif |
| |
| #ifndef CHIP_RETAIN_LOGGING |
| #define CHIP_RETAIN_LOGGING CHIP_PROGRESS_LOGGING |
| #define ChipLogRetain(MOD, MSG, ...) ChipLogProgress(MOD, MSG, ##__VA_ARGS__) |
| #endif |
| |
| #if CHIP_RETAIN_LOGGING |
| /** |
| * @def ChipLogRetain(MOD, MSG, ...) |
| * |
| * @brief |
| * Log a chip message for the specified module in the 'Retain' |
| * category. This is used for IE testing. |
| * If the product has not defined CHIP_RETAIN_LOGGING, it defaults to the same as ChipLogProgress |
| * |
| */ |
| #ifndef ChipLogRetain |
| #define ChipLogRetain(MOD, MSG, ...) \ |
| chip::Logging::Log(chip::Logging::kLogModule_##MOD, chip::Logging::kLogCategory_Retain, MSG, ##__VA_ARGS__) |
| #endif |
| |
| #else // #if CHIP_RETAIN_LOGGING |
| #ifdef ChipLogRetain |
| // This is to ensure that ChipLogRetain is null if |
| // the product has defined CHIP_RETAIN_LOGGING to 0 itself |
| #undef ChipLogRetain |
| #endif |
| #define ChipLogRetain(MOD, MSG, ...) |
| #endif // #if CHIP_RETAIN_LOGGING |
| |
| #if CHIP_ERROR_LOGGING || CHIP_PROGRESS_LOGGING || CHIP_DETAIL_LOGGING || CHIP_RETAIN_LOGGING |
| #define _CHIP_USE_LOGGING 1 |
| #else |
| #define _CHIP_USE_LOGGING 0 |
| #endif /* CHIP_ERROR_LOGGING || CHIP_PROGRESS_LOGGING || CHIP_DETAIL_LOGGING || CHIP_RETAIN_LOGGING */ |
| |
| #if _CHIP_USE_LOGGING |
| |
| #define ChipLoggingChipPrefixLen 6 |
| #define ChipLoggingModuleNameLen 3 |
| #define ChipLoggingMessageSeparatorLen 2 |
| #define ChipLoggingMessageTrailerLen 2 |
| #define ChipLoggingTotalMessagePadding \ |
| (ChipLoggingchipPrefixLen + ChipLoggingModuleNameLen + ChipLoggingMessageSeparatorLen + ChipLoggingMessageTrailerLen) |
| |
| extern void GetMessageWithPrefix(char * buf, uint8_t bufSize, uint8_t module, const char * msg); |
| extern void GetModuleName(char * buf, uint8_t module); |
| extern void PrintMessagePrefix(uint8_t module); |
| |
| #else |
| |
| static inline void GetMessageWithPrefix(char * buf, uint8_t bufSize, uint8_t module, const char * msg) |
| { |
| return; |
| } |
| |
| static inline void GetModuleName(char * buf, uint8_t module) |
| { |
| return; |
| } |
| |
| #endif // _CHIP_USE_LOGGING |
| |
| extern bool IsCategoryEnabled(uint8_t CAT); |
| |
| /** |
| * @def ChipLogIfFalse(aCondition) |
| * |
| * @brief |
| * This checks for the specified condition, which is expected to |
| * commonly be true and emits some log, based on configuration, if |
| * the condition is false. |
| * |
| * @note |
| * Evaluation of @a aCondition is always done, but logging is only enabled when |
| * #CHIP_CONFIG_ENABLE_CONDITION_LOGGING is enabled. This can be turned on or |
| * off for each compilation unit by enabling or disabling, as desired, |
| * #CHIP_CONFIG_ENABLE_CONDITION_LOGGING before ChipLogging.h is included by |
| * the preprocessor. |
| * |
| * Example Usage: |
| * |
| * @code |
| * #define CHIP_CONFIG_ENABLE_CONDITION_LOGGING 1 |
| * |
| * #include <chip/Support/Logging/ChipLogging.h> |
| * |
| * ... |
| * |
| * void foo(void) |
| * { |
| * CHIP_ERROR err = CHIP_NO_ERROR; |
| * |
| * ... |
| * |
| * exit: |
| * ChipLogIfFalse(CHIP_END_OF_TLV == err); |
| * } |
| * @endcode |
| * |
| * @param[in] aCondition A Boolean expression to be evaluated. |
| * |
| * @sa CHIP_CONFIG_ENABLE_TRACE_ON_CHECK_FAILURE |
| * |
| */ |
| |
| #if CHIP_CONFIG_ENABLE_CONDITION_LOGGING && !defined(ChipLogIfFalse) |
| |
| #define ChipLogIfFalse(aCondition) \ |
| do \ |
| { \ |
| if (!(aCondition)) \ |
| { \ |
| ChipLogError(NotSpecified, "Condition Failed (%s) at %s:%d", #aCondition, __FILE__, __LINE__); \ |
| } \ |
| } while (0) |
| |
| #else // CHIP_CONFIG_ENABLE_CONDITION_LOGGING |
| |
| #define ChipLogIfFalse(aCondition) IgnoreUnusedVariable(aCondition) |
| |
| #endif // CHIP_CONFIG_ENABLE_CONDITION_LOGGING |
| |
| /** |
| * @def ChipLogFunctError(aErr) |
| * |
| * @brief |
| * If the given error value (@a aErr) is not successful (!= CHIP_NO_ERROR), |
| * the method logs the file name, line number, and the error code. |
| * |
| * @note |
| * Evaluation of @a aErr is always done, but logging is only enabled when |
| * #CHIP_CONFIG_ENABLE_FUNCT_ERROR_LOGGING is enabled. This can be turned |
| * on or off for each compilation unit by enabling or disabling, as desired, |
| * #CHIP_CONFIG_ENABLE_FUNCT_ERROR_LOGGING before ChipLogging.h is included |
| * by the preprocessor. |
| * |
| * Example Usage: |
| * |
| * @code |
| * #define CHIP_CONFIG_ENABLE_FUNCT_ERROR_LOGGING 1 |
| * |
| * #include <chip/Support/Logging/ChipLogging.h> |
| * |
| * ... |
| * |
| * void foo(void) |
| * { |
| * CHIP_ERROR err = CHIP_NO_ERROR; |
| * |
| * ... |
| * |
| * exit: |
| * ChipLogFunctError(err); |
| * } |
| * @endcode |
| * |
| * @param[in] aErr A scalar status to be evaluated against CHIP_NO_ERROR. |
| * |
| * @sa #CHIP_CONFIG_ENABLE_FUNCT_ERROR_LOGGING |
| * |
| */ |
| |
| #if CHIP_CONFIG_ENABLE_FUNCT_ERROR_LOGGING && !defined(ChipLogFunctError) |
| |
| #define ChipLogFunctError(aErr) \ |
| do \ |
| { \ |
| if ((aErr) != CHIP_NO_ERROR) \ |
| { \ |
| ChipLogError(NotSpecified, "%s at %s:%d", ErrorStr(aErr), __FILE__, __LINE__); \ |
| } \ |
| } while (0) |
| |
| #else // CHIP_CONFIG_ENABLE_FUNCT_ERROR_LOGGING |
| |
| #define ChipLogFunctError(aErr) IgnoreUnusedVariable(aErr) |
| |
| #endif // CHIP_CONFIG_ENABLE_FUNCT_ERROR_LOGGING |
| |
| } // namespace Logging |
| } // namespace chip |
| |
| #endif /* CHIPLOGGING_H_ */ |