2020-11-26 10:24:23 +01:00
|
|
|
#ifndef GS_UTIL_LOG_LOG_H
|
|
|
|
#define GS_UTIL_LOG_LOG_H
|
|
|
|
/* Copyright (c) 2013-2018 GomSpace A/S. All rights reserved. */
|
|
|
|
/**
|
|
|
|
@file
|
|
|
|
|
|
|
|
Log interface.
|
|
|
|
|
|
|
|
Logging is done through groups (domains), where the level mask can be changed runtime.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <gs/util/error.h>
|
|
|
|
#include <gs/util/timestamp.h>
|
|
|
|
#include <gs/util/pgm.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Name of the root log group
|
|
|
|
*/
|
|
|
|
#define GS_LOG_GROUP_ROOT "root"
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log levels.
|
|
|
|
|
|
|
|
The levels can easily be mapped to standard syslog severity levels (https://en.wikipedia.org/wiki/Syslog).
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
/**
|
|
|
|
Trace (more detailed than \a debug).
|
|
|
|
|
|
|
|
syslog: maps to \a debug (or \a trace if supported).
|
|
|
|
*/
|
|
|
|
GS_LOG_TRACE = 0,
|
|
|
|
/**
|
|
|
|
Debug.
|
|
|
|
|
|
|
|
syslog: maps to \a debug.
|
|
|
|
*/
|
|
|
|
GS_LOG_DEBUG = 1,
|
|
|
|
/**
|
|
|
|
Informational.
|
|
|
|
|
|
|
|
syslog: maps to \a informational.
|
|
|
|
*/
|
|
|
|
GS_LOG_INFO = 2,
|
|
|
|
/**
|
|
|
|
Normal but significant conditions.
|
|
|
|
|
|
|
|
syslog: maps to \a notice.
|
|
|
|
*/
|
|
|
|
GS_LOG_NOTICE = 3,
|
|
|
|
/**
|
|
|
|
Warning.
|
|
|
|
|
|
|
|
syslog: maps to \a warning.
|
|
|
|
*/
|
|
|
|
GS_LOG_WARNING = 4,
|
|
|
|
/**
|
|
|
|
Error.
|
|
|
|
|
|
|
|
syslog: maps to \a error.
|
|
|
|
*/
|
|
|
|
GS_LOG_ERROR = 5,
|
|
|
|
|
|
|
|
/**
|
|
|
|
Trace (more detailed than \a debug).
|
|
|
|
@deprecated use #GS_LOG_TRACE
|
|
|
|
*/
|
|
|
|
LOG_TRACE = GS_LOG_TRACE,
|
|
|
|
/**
|
|
|
|
Debug.
|
|
|
|
@deprecated use #GS_LOG_DEBUG
|
|
|
|
*/
|
|
|
|
LOG_DEBUG = GS_LOG_DEBUG,
|
|
|
|
/**
|
|
|
|
Informational.
|
|
|
|
@deprecated use #GS_LOG_INFO
|
|
|
|
*/
|
|
|
|
LOG_INFO = GS_LOG_INFO,
|
|
|
|
/**
|
|
|
|
Normal but significant conditions.
|
|
|
|
@deprecated use #GS_LOG_NOTICE
|
|
|
|
*/
|
|
|
|
LOG_NOTICE = GS_LOG_NOTICE,
|
|
|
|
/**
|
|
|
|
Warning.
|
|
|
|
@deprecated use #GS_LOG_WARNING
|
|
|
|
*/
|
|
|
|
LOG_WARNING = GS_LOG_WARNING,
|
|
|
|
/**
|
|
|
|
Error.
|
|
|
|
@deprecated use #GS_LOG_ERROR
|
|
|
|
*/
|
|
|
|
LOG_ERROR = GS_LOG_ERROR,
|
|
|
|
} gs_log_level_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log categories.
|
|
|
|
|
|
|
|
The category is a way of grouping information about which sub-systems have logged. It is primarily used in the \a
|
|
|
|
telemetry table, to indicate what sub-systems have logged an \a error or \a warning - indicating a possible problem.
|
|
|
|
|
|
|
|
Up to 32 categories are supported (stored in a uint32).
|
|
|
|
|
|
|
|
Categories should be unique within a single node. However, nothing happens if categories clashes - it will only be more difficult to determine what part of the system logged.
|
|
|
|
|
|
|
|
Standard categories are defined from #GS_LOG_CAT_1 and up. Products or mission specific software should start from #GS_LOG_CAT_32 and down.
|
|
|
|
*/
|
|
|
|
typedef enum {
|
|
|
|
//! Standard, used for #GS_LOG_CAT_DEFAULT
|
|
|
|
GS_LOG_CAT_1 = 1 << 0,
|
|
|
|
//! Standard, used for #GS_LOG_CAT_DRIVER
|
|
|
|
GS_LOG_CAT_2 = 1 << 1,
|
|
|
|
//! Standard, used for #GS_LOG_CAT_CSP
|
|
|
|
GS_LOG_CAT_3 = 1 << 2,
|
|
|
|
//! Standard, used for #GS_LOG_CAT_PARAM
|
|
|
|
GS_LOG_CAT_4 = 1 << 3,
|
|
|
|
//! Standard, used for #GS_LOG_CAT_FILE_SYSTEM
|
|
|
|
GS_LOG_CAT_5 = 1 << 4,
|
|
|
|
//! Standard, used for #GS_LOG_CAT_COMMAND
|
|
|
|
GS_LOG_CAT_6 = 1 << 5,
|
|
|
|
//! Standard, used for #GS_LOG_CAT_HK
|
|
|
|
GS_LOG_CAT_7 = 1 << 6,
|
|
|
|
//! Standard, used for #GS_LOG_CAT_FP
|
|
|
|
GS_LOG_CAT_8 = 1 << 7,
|
|
|
|
//! Standard, used for #GS_LOG_CAT_ADCS
|
|
|
|
GS_LOG_CAT_9 = 1 << 8,
|
|
|
|
GS_LOG_CAT_10 = 1 << 9,
|
|
|
|
GS_LOG_CAT_11 = 1 << 10,
|
|
|
|
GS_LOG_CAT_12 = 1 << 11,
|
|
|
|
GS_LOG_CAT_13 = 1 << 12,
|
|
|
|
GS_LOG_CAT_14 = 1 << 13,
|
|
|
|
GS_LOG_CAT_15 = 1 << 14,
|
|
|
|
GS_LOG_CAT_16 = 1 << 15,
|
|
|
|
#if (__AVR__ == 0)
|
|
|
|
GS_LOG_CAT_17 = 1 << 16,
|
|
|
|
GS_LOG_CAT_18 = 1 << 17,
|
|
|
|
GS_LOG_CAT_19 = 1 << 18,
|
|
|
|
GS_LOG_CAT_20 = 1 << 19,
|
|
|
|
GS_LOG_CAT_21 = 1 << 20,
|
|
|
|
GS_LOG_CAT_22 = 1 << 21,
|
|
|
|
GS_LOG_CAT_23 = 1 << 22,
|
|
|
|
GS_LOG_CAT_24 = 1 << 23,
|
|
|
|
GS_LOG_CAT_25 = 1 << 24,
|
|
|
|
GS_LOG_CAT_26 = 1 << 25,
|
|
|
|
GS_LOG_CAT_27 = 1 << 26,
|
|
|
|
GS_LOG_CAT_28 = 1 << 27,
|
|
|
|
GS_LOG_CAT_29 = 1 << 28,
|
|
|
|
GS_LOG_CAT_30 = 1 << 29,
|
|
|
|
GS_LOG_CAT_31 = 1 << 30,
|
|
|
|
//! Product or mission specific - start here and down
|
|
|
|
GS_LOG_CAT_32 = 1 << 31,
|
|
|
|
#endif
|
|
|
|
} gs_log_category_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
@defgroup reserved_log_categories Reserved/assigned log categories.
|
|
|
|
These categories are assigned/reserved for certain sub-systems.
|
|
|
|
@{
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
Default, used if nothing else fits.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_DEFAULT GS_LOG_CAT_1
|
|
|
|
/**
|
|
|
|
Driver layer.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_DRIVER GS_LOG_CAT_2
|
|
|
|
/**
|
|
|
|
CSP.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_CSP GS_LOG_CAT_3
|
|
|
|
/**
|
|
|
|
Parameter system.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_PARAM GS_LOG_CAT_4
|
|
|
|
/**
|
|
|
|
File system.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_FILE_SYSTEM GS_LOG_CAT_5
|
|
|
|
/**
|
|
|
|
Command framework and execution.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_COMMAND GS_LOG_CAT_6
|
|
|
|
/**
|
|
|
|
Housekeeping System.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_HK GS_LOG_CAT_7
|
|
|
|
/**
|
|
|
|
Flight Planner.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_FP GS_LOG_CAT_8
|
|
|
|
/**
|
|
|
|
ADCS
|
|
|
|
*/
|
|
|
|
#define GS_LOG_CAT_ADCS GS_LOG_CAT_9
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
struct gs_log_list; /* forward declared private log list struct */
|
|
|
|
/**
|
|
|
|
Log list type (private)
|
|
|
|
|
|
|
|
Private gs_log_list type.
|
|
|
|
*/
|
|
|
|
typedef struct gs_log_list gs_log_list_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log group.
|
|
|
|
All logs are logged to a \a group. The group contains the current log level mask,
|
|
|
|
which controls whether the log is carried through or not.
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
/**
|
|
|
|
Name of log group.
|
|
|
|
*/
|
|
|
|
const char * name;
|
|
|
|
/**
|
|
|
|
Category, see #gs_log_category_t.
|
|
|
|
*/
|
|
|
|
uint32_t category;
|
|
|
|
/**
|
|
|
|
Current level mask, see #gs_log_level_t.
|
|
|
|
*/
|
|
|
|
uint8_t mask;
|
|
|
|
/**
|
|
|
|
Is group additive, if \a true (default) logging will be done on both root appenders and this groups appenders - if \a false, logging will only be done to this groups appenders.
|
|
|
|
*/
|
|
|
|
bool additivity;
|
|
|
|
/**
|
|
|
|
Private list of appenders.
|
|
|
|
*/
|
|
|
|
gs_log_list_t * appenders;
|
|
|
|
#if (__AVR__)
|
|
|
|
uint16_t dummy_align;
|
|
|
|
#endif
|
|
|
|
} gs_log_group_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log masks (levels converted to mask).
|
|
|
|
@{
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
Trace level enabled.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_TRACE_MASK (1 << GS_LOG_TRACE)
|
|
|
|
/**
|
|
|
|
Debug level enabled.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_DEBUG_MASK (1 << GS_LOG_DEBUG)
|
|
|
|
/**
|
|
|
|
Info level enabled.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_INFO_MASK (1 << GS_LOG_INFO)
|
|
|
|
/**
|
|
|
|
Notice level enabled.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_NOTICE_MASK (1 << GS_LOG_NOTICE)
|
|
|
|
/**
|
|
|
|
Warning level enabled.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_WARNING_MASK (1 << GS_LOG_WARNING)
|
|
|
|
/**
|
|
|
|
Error level enabled.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_ERROR_MASK (1 << GS_LOG_ERROR)
|
|
|
|
/**
|
|
|
|
All levels enabled.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_ALL_MASK (GS_LOG_TRACE_MASK | GS_LOG_DEBUG_MASK | GS_LOG_INFO_MASK | GS_LOG_NOTICE_MASK | GS_LOG_WARNING_MASK | GS_LOG_ERROR_MASK)
|
|
|
|
/**
|
|
|
|
Default levels enabled - #GS_LOG_ERROR, #GS_LOG_WARNING and #GS_LOG_NOTICE.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_DEFAULT_MASK (GS_LOG_ERROR_MASK | GS_LOG_WARNING_MASK | GS_LOG_NOTICE_MASK)
|
|
|
|
/**
|
|
|
|
Trace level enabled.
|
|
|
|
@deprecated use #GS_LOG_TRACE_MASK
|
|
|
|
*/
|
|
|
|
#define LOG_TRACE_MASK GS_LOG_TRACE_MASK
|
|
|
|
/**
|
|
|
|
Debug level enabled.
|
|
|
|
@deprecated use #GS_LOG_DEBUG_MASK
|
|
|
|
*/
|
|
|
|
#define LOG_DEBUG_MASK GS_LOG_DEBUG_MASK
|
|
|
|
/**
|
|
|
|
Info level enabled.
|
|
|
|
@deprecated use #GS_LOG_INFO_MASK
|
|
|
|
*/
|
|
|
|
#define LOG_INFO_MASK GS_LOG_INFO_MASK
|
|
|
|
/**
|
|
|
|
Notice level enabled.
|
|
|
|
@deprecated use #GS_LOG_NOTICE_MASK
|
|
|
|
*/
|
|
|
|
#define LOG_NOTICE_MASK GS_LOG_NOTICE_MASK
|
|
|
|
/**
|
|
|
|
Warning level enabled.
|
|
|
|
@deprecated use #GS_LOG_WARNING_MASK
|
|
|
|
*/
|
|
|
|
#define LOG_WARNING_MASK GS_LOG_WARNING_MASK
|
|
|
|
/**
|
|
|
|
Error level enabled.
|
|
|
|
@deprecated use #GS_LOG_ERROR_MASK
|
|
|
|
*/
|
|
|
|
#define LOG_ERROR_MASK GS_LOG_ERROR_MASK
|
|
|
|
/**
|
|
|
|
All levels enabled.
|
|
|
|
@deprecated use #GS_LOG_ALL_MASK
|
|
|
|
*/
|
|
|
|
#define LOG_ALL_MASK GS_LOG_ALL_MASK
|
|
|
|
/**
|
|
|
|
Default levels enabled - #GS_LOG_ERROR, #GS_LOG_WARNING and #GS_LOG_NOTICE.
|
|
|
|
@deprecated use #GS_LOG_DEFAULT_MASK
|
|
|
|
*/
|
|
|
|
#define LOG_DEFAULT_MASK GS_LOG_DEFAULT_MASK
|
|
|
|
/**@}*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
Define/Create a log group.
|
|
|
|
|
|
|
|
@note name clash: This defines a variable, which potentially is \a global, meaning possibility of name clashes. Therefore log group should always
|
|
|
|
be prefixed with something that makes it fairly unique, i.e. component name. Example: gs_a3200dock_log - log group used by liba3200dock library.
|
|
|
|
|
|
|
|
@param[in] group name of variables created. See note above about name clash.
|
|
|
|
@param[in] name_in display name
|
|
|
|
@param[in] cat_in log group category
|
|
|
|
@param[in] level_mask log level mask.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_GROUP(group, name_in, cat_in, level_mask) \
|
|
|
|
gs_log_group_t group##_s = {.name = name_in, .category = cat_in, \
|
|
|
|
.mask = level_mask, .additivity = true, \
|
|
|
|
.appenders = NULL}; \
|
|
|
|
gs_log_group_t * group = &group##_s
|
|
|
|
|
|
|
|
/**
|
|
|
|
Define log group with initial mask for \a print and \a store.
|
|
|
|
|
|
|
|
@note name clash: This defines a variable, which potentially is \a global, meaning possibility of name clashes. Therefore log group should always
|
|
|
|
be prefixed with something that makes it fairly unique, i.e. component name. Example: gs_a3200dock_log - log group used by liba3200dock library.
|
|
|
|
|
|
|
|
@deprecated This MACRO is no longer supported, use #GS_LOG_GROUP(...) instead.
|
|
|
|
|
|
|
|
@param[in] group name of variables created. See note above about name clash.
|
|
|
|
@param[in] name_in display name
|
|
|
|
@param[in] print_mask enable mask for \a print.
|
|
|
|
@param[in] store_mask enable mask for \a store.
|
|
|
|
*/
|
|
|
|
#define LOG_GROUP_MASKED(group, name_in, print_mask, store_mask) GS_LOG_GROUP(group, name_in, GS_LOG_CAT_DEFAULT, (print_mask | store_mask))
|
|
|
|
|
|
|
|
/**
|
|
|
|
Declare log group as external (defined else where).
|
|
|
|
|
|
|
|
@param[in] group the log group variable defined elsewhere.
|
|
|
|
*/
|
|
|
|
#define GS_LOG_GROUP_EXTERN(group) extern gs_log_group_t * group
|
|
|
|
|
|
|
|
/**
|
|
|
|
Define log group - levels are #GS_LOG_DEFAULT_MASK
|
|
|
|
|
|
|
|
@deprecated This MACRO is no longer supported, use #GS_LOG_GROUP(..) instead.
|
|
|
|
*/
|
|
|
|
#define LOG_GROUP(group, name_in) GS_LOG_GROUP(group, name_in, GS_LOG_CAT_DEFAULT, LOG_DEFAULT_MASK)
|
|
|
|
|
|
|
|
/**
|
|
|
|
Define verbose log group - all levels are enabled (#GS_LOG_ALL_MASK)
|
|
|
|
|
|
|
|
@deprecated This MACRO is no longer supported, use #GS_LOG_GROUP(..) instead.
|
|
|
|
*/
|
|
|
|
#define LOG_GROUP_VERBOSE(group, name_in) GS_LOG_GROUP(group, name_in, GS_LOG_CAT_DEFAULT, LOG_ALL_MASK)
|
|
|
|
|
|
|
|
/**
|
|
|
|
Define silent log group - all levels are disabled.
|
|
|
|
|
|
|
|
@deprecated This MACRO is no longer supported, use #GS_LOG_GROUP(..) instead.
|
|
|
|
*/
|
|
|
|
#define LOG_GROUP_SILENT(group, name_in) GS_LOG_GROUP(group, name_in, GS_LOG_CAT_DEFAULT, 0)
|
|
|
|
|
|
|
|
/**
|
|
|
|
Declare log group as external (defined else where).
|
|
|
|
|
|
|
|
@deprecated use #GS_LOG_GROUP_EXTERN(...) instead.
|
|
|
|
*/
|
|
|
|
#define LOG_GROUP_EXTERN(group) GS_LOG_GROUP_EXTERN(group)
|
|
|
|
|
|
|
|
/**
|
|
|
|
Default log group.
|
|
|
|
This can be overridden by a define
|
|
|
|
*/
|
|
|
|
extern gs_log_group_t * LOG_DEFAULT;
|
|
|
|
|
|
|
|
/**
|
|
|
|
Initializes the log system.
|
|
|
|
|
|
|
|
@param[in] with_console_appender Enable/Disable console log appender
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
gs_error_t gs_log_init(bool with_console_appender);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Set log group level mask.
|
|
|
|
|
|
|
|
@param[in] group_name log group name
|
|
|
|
@param[in] mask level mask to set.
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
gs_error_t gs_log_group_set_level_mask(const char * group_name, uint8_t mask);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Get log group level mask.
|
|
|
|
|
|
|
|
@param[in] group_name log group name
|
|
|
|
@param[out] mask returned current level mask.
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
gs_error_t gs_log_group_get_level_mask(const char * group_name, uint8_t *mask);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log group iterator callback function
|
|
|
|
|
|
|
|
@param[in] ctx context data for iterator.
|
|
|
|
@param[in] group log group being iterated.
|
|
|
|
|
|
|
|
@return true/false: Return false to discontinue iteration.
|
|
|
|
*/
|
|
|
|
typedef bool (*gs_log_group_iterator_t)(void *ctx, gs_log_group_t * group);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Iterate all or specific log group(s).
|
|
|
|
|
|
|
|
@param[in] group_name name of log group, or NULL/\"all\" for all groups.
|
|
|
|
@param[in] ctx user context data.
|
|
|
|
@param[in] iter iterator, return \a true to continue, \a false to break iteration.
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
gs_error_t gs_log_group_iterate(const char * group_name, void * ctx, gs_log_group_iterator_t iter);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Register a log group in the log system.
|
|
|
|
|
|
|
|
The log group will be added to a system wide list of log groups, enabling list and set of level.
|
|
|
|
|
|
|
|
@note The group must remain valid during the life-time of the application.
|
|
|
|
|
|
|
|
@param[in] group The log group to be added to the system.
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
gs_error_t gs_log_group_register(gs_log_group_t *group);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Register a log group in the log system.
|
|
|
|
|
|
|
|
@note The group must stay in memory during the life-time of the application
|
|
|
|
@see gs_log_group_register()
|
|
|
|
@param[in] group The log group to be added to the system.
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
static inline gs_error_t gs_log_group_add(gs_log_group_t *group)
|
|
|
|
{
|
|
|
|
return gs_log_group_register(group);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Checks if a level is enabled on a log group
|
|
|
|
|
|
|
|
@param[in] group The log group to check.
|
|
|
|
@param[in] level The log level to check if it's set on the group.
|
|
|
|
@return bool (true if enabled / false if not enabled)
|
|
|
|
*/
|
|
|
|
bool gs_log_group_is_level_enabled(gs_log_group_t *group, gs_log_level_t level);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert string to log level.
|
|
|
|
|
|
|
|
@param[in] str log level.
|
|
|
|
@param[out] return_level converted log level.
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
gs_error_t gs_log_string_to_level(const char * str, gs_log_level_t * return_level);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert level to single character.
|
|
|
|
|
|
|
|
@param[in] level log level
|
|
|
|
@return single character representing the \a level.
|
|
|
|
*/
|
|
|
|
char gs_log_level_to_char(gs_log_level_t level);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Register Log commands.
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
gs_error_t gs_log_register_commands(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Generic log.
|
|
|
|
@note This function should not be called directly, use log macros.
|
|
|
|
|
|
|
|
@param level log level
|
|
|
|
@param group log group. If NULL, the \a default log group will be used.
|
|
|
|
@param format Format string (printf style).
|
|
|
|
*/
|
|
|
|
void gs_log(gs_log_level_t level, gs_log_group_t * group, const char * format, ...) __attribute__ ((format (__printf__, 3, 4)));
|
|
|
|
|
|
|
|
/**
|
|
|
|
Generic log from ISR.
|
|
|
|
@note This function should not be called directly, use log macros.
|
|
|
|
|
|
|
|
@param level log level
|
|
|
|
@param group log group. If NULL, the \a default log group will be used.
|
|
|
|
@param format Format string (printf style).
|
|
|
|
*/
|
|
|
|
void gs_log_isr(gs_log_level_t level, gs_log_group_t * group, const char * format, ...) __attribute__ ((format (__printf__, 3, 4)));
|
|
|
|
|
|
|
|
/**
|
|
|
|
Generic log (va_list).
|
|
|
|
@note This function should not be called directly, use log macros.
|
|
|
|
|
|
|
|
@param level log level
|
|
|
|
@param group log group. If NULL, the \a default log group will be used.
|
|
|
|
@param format Format string (printf style).
|
|
|
|
@param args arguments for \a format.
|
|
|
|
*/
|
|
|
|
void gs_log_va(gs_log_level_t level, gs_log_group_t * group, const char * format, va_list args);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Enable/disable color in \a print logs.
|
|
|
|
Default is \a enabled/true.
|
|
|
|
|
|
|
|
@param[in] color \a true to enable color, \a false disable color.
|
|
|
|
*/
|
|
|
|
void gs_log_set_print_color(bool color);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Level to color (begin).
|
|
|
|
|
|
|
|
@param[in] level log level.
|
|
|
|
@return color string.
|
|
|
|
*/
|
|
|
|
const char * gs_log_level_to_color_begin(gs_log_level_t level);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Level to color (end).
|
|
|
|
|
|
|
|
@return color string.
|
|
|
|
*/
|
|
|
|
const char * gs_log_level_to_color_end(void);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Take a level as input an create a level mask enabling all
|
|
|
|
levels with priority >= level.
|
|
|
|
|
|
|
|
If level is e.g. LOG_INFO, the mask will enable Error, Warn & Info.
|
|
|
|
|
|
|
|
* @param level the log level.
|
|
|
|
* @return level mask
|
|
|
|
*/
|
|
|
|
uint8_t gs_log_level_to_mask(gs_log_level_t level);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Convert string to log mask.
|
|
|
|
|
|
|
|
Format: [+-]level[,[+-]level]
|
|
|
|
|
|
|
|
+ add level, - remove level.
|
|
|
|
|
|
|
|
@param[in] str log mask
|
|
|
|
@param[in] current_mask current mask, used when input format contains + or -.
|
|
|
|
@param[out] return_mask converted log mask.
|
|
|
|
@return_gs_error_t
|
|
|
|
*/
|
|
|
|
gs_error_t gs_log_string_to_mask(const char *str, uint8_t current_mask, uint8_t * return_mask);
|
|
|
|
|
|
|
|
#if !(__DOXYGEN__)
|
|
|
|
/**
|
|
|
|
Internal macro for checking if log is enabled, before making log.
|
|
|
|
*/
|
|
|
|
#define __gs_log(level, group, format, ...) \
|
|
|
|
if (group->mask & (1 << level)) { \
|
|
|
|
gs_log(level, group, GS_PGM_STR(format), ##__VA_ARGS__); \
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Internal macro for checking if log is enabled for isr, before making log.
|
|
|
|
*/
|
|
|
|
#define __gs_log_isr(level, group, format, ...) \
|
|
|
|
if (group->mask & (1 << level)) { \
|
|
|
|
gs_log_isr(level, group, GS_PGM_STR(format), ##__VA_ARGS__); \
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Internal macro used for performing a log only once.
|
|
|
|
@note This creates a \a static \a variable.
|
|
|
|
*/
|
|
|
|
#define __gs_log_once(level, group, format, ...) \
|
|
|
|
({ \
|
|
|
|
static bool print_once; \
|
|
|
|
if (!print_once) { \
|
|
|
|
print_once = true; \
|
|
|
|
__gs_log(level, group, format, ##__VA_ARGS__); \
|
|
|
|
} \
|
|
|
|
})
|
|
|
|
#endif // __DOXYGEN__
|
|
|
|
|
|
|
|
/**
|
|
|
|
Default compile-time enabling/disabling of all levels
|
|
|
|
Unless levels are individually defined, this will be the default value.
|
|
|
|
*/
|
|
|
|
#if !defined(GS_LOG_DISABLE_ALL)
|
2020-11-28 13:41:30 +01:00
|
|
|
#define GS_LOG_DISABLE_ALL 1
|
2020-11-26 10:24:23 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Disable \a error level compile-time by defining a value > 0
|
|
|
|
*/
|
|
|
|
#if !defined(GS_LOG_DISABLE_ERROR)
|
|
|
|
#define GS_LOG_DISABLE_ERROR GS_LOG_DISABLE_ALL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Disable \a warning level compile-time by defining a value > 0
|
|
|
|
*/
|
|
|
|
#if !defined(GS_LOG_DISABLE_WARNING)
|
|
|
|
#define GS_LOG_DISABLE_WARNING GS_LOG_DISABLE_ALL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Disable \a notice level compile-time by defining a value > 0
|
|
|
|
*/
|
|
|
|
#if !defined(GS_LOG_DISABLE_NOTICE)
|
|
|
|
#define GS_LOG_DISABLE_NOTICE GS_LOG_DISABLE_ALL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Disable \a info level compile-time by defining a value > 0
|
|
|
|
*/
|
|
|
|
#if !defined(GS_LOG_DISABLE_INFO)
|
|
|
|
#define GS_LOG_DISABLE_INFO GS_LOG_DISABLE_ALL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Disable \a debug level compile-time by defining a value > 0
|
|
|
|
*/
|
|
|
|
#if !defined(GS_LOG_DISABLE_DEBUG)
|
|
|
|
#define GS_LOG_DISABLE_DEBUG GS_LOG_DISABLE_ALL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Disable \a trace level compile-time by defining a value > 0
|
|
|
|
*/
|
|
|
|
#if !defined(GS_LOG_DISABLE_TRACE)
|
|
|
|
#define GS_LOG_DISABLE_TRACE GS_LOG_DISABLE_ALL
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a error to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_error(format, ...) { if (!GS_LOG_DISABLE_ERROR) __gs_log(LOG_ERROR, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a error from ISR to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_error_isr(format, ...) { if (!GS_LOG_DISABLE_ERROR) __gs_log_isr(LOG_ERROR, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a error to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_error_group(group, format, ...) { if (!GS_LOG_DISABLE_ERROR) __gs_log(LOG_ERROR, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a error only once to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_error_once(format, ...) { if (!GS_LOG_DISABLE_ERROR) __gs_log_once(LOG_ERROR, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a error only once to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_error_once_group(group, format, ...) { if (!GS_LOG_DISABLE_ERROR) __gs_log_once(LOG_ERROR, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a warning to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_warning(format, ...) { if (!GS_LOG_DISABLE_WARNING) __gs_log(LOG_WARNING, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a warning from ISR to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_warning_isr(format, ...) { if (!GS_LOG_DISABLE_WARNING) __gs_log_isr(LOG_WARNING, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a warning to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_warning_group(group, format, ...) { if (!GS_LOG_DISABLE_WARNING) __gs_log(LOG_WARNING, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a warning only once to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_warning_once(format, ...) { if (!GS_LOG_DISABLE_WARNING) __gs_log_once(LOG_WARNING, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a warning only once to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_warning_once_group(group, format, ...) { if (!GS_LOG_DISABLE_WARNING) __gs_log_once(LOG_WARNING, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a notice to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_notice(format, ...) { if (!GS_LOG_DISABLE_NOTICE) __gs_log(LOG_NOTICE, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a notice from ISR to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_notice_isr(format, ...) { if (!GS_LOG_DISABLE_NOTICE) __gs_log_isr(LOG_NOTICE, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a notice to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_notice_group(group, format, ...) { if (!GS_LOG_DISABLE_NOTICE) __gs_log(LOG_NOTICE, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a notice only once to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_notice_once(format, ...) { if (!GS_LOG_DISABLE_NOTICE) __gs_log_once(LOG_NOTICE, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a notice only once to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_notice_once_group(group, format, ...) { if (!GS_LOG_DISABLE_NOTICE) __gs_log_once(LOG_NOTICE, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a info to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_info(format, ...) { if (!GS_LOG_DISABLE_INFO) __gs_log(LOG_INFO, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a info from ISR to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_info_isr(format, ...) { if (!GS_LOG_DISABLE_INFO) __gs_log_isr(LOG_INFO, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a info to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_info_group(group, format, ...) { if (!GS_LOG_DISABLE_INFO) __gs_log(LOG_INFO, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a info only once to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_info_once(format, ...) { if (!GS_LOG_DISABLE_INFO) __gs_log_once(LOG_INFO, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a info only once to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_info_once_group(group, format, ...) { if (!GS_LOG_DISABLE_INFO) __gs_log_once(LOG_INFO, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a debug to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_debug(format, ...) { if (!GS_LOG_DISABLE_DEBUG) __gs_log(LOG_DEBUG, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a debug from ISR to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_debug_isr(format, ...) { if (!GS_LOG_DISABLE_DEBUG) __gs_log_isr(LOG_DEBUG, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a debug to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_debug_group(group, format, ...) { if (!GS_LOG_DISABLE_DEBUG) __gs_log(LOG_DEBUG, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a debug only once to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_debug_once(format, ...) { if (!GS_LOG_DISABLE_DEBUG) __gs_log_once(LOG_DEBUG, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a debug only once to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_debug_once_group(group, format, ...) { if (!GS_LOG_DISABLE_DEBUG) __gs_log_once(LOG_DEBUG, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a trace to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_trace(format, ...) { if (!GS_LOG_DISABLE_TRACE) __gs_log(LOG_TRACE, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a trace from ISR to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_trace_isr(format, ...) { if (!GS_LOG_DISABLE_TRACE) __gs_log_isr(LOG_TRACE, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a trace to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_trace_group(group, format, ...) { if (!GS_LOG_DISABLE_TRACE) __gs_log(LOG_TRACE, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a trace only once to default group (LOG_DEFAULT).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_trace_once(format, ...) { if (!GS_LOG_DISABLE_TRACE) __gs_log_once(LOG_TRACE, LOG_DEFAULT, format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
Log \a trace only once to group.
|
|
|
|
@param[in] group log group (gs_log_group_t *).
|
|
|
|
@param[in] format Format string (printf style).
|
|
|
|
*/
|
|
|
|
#define log_trace_once_group(group, format, ...) { if (!GS_LOG_DISABLE_TRACE) __gs_log_once(LOG_TRACE, (group), format, ##__VA_ARGS__); }
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|