Skip to content

Commit 5e34681

Browse files
nordic-krchnashif
authored andcommitted
logging: Refactor LOG_MODULE_REGISTER and LOG_MODULE_DECLARE macros
Changed LOG_MODULE_REGISTER and LOG_MODULE_DECLARE macros to take log level as optional parameter. LOG_MODULE_DECLARE can now also be used in static inline functions in headers. Added LOG_LEVEL_SET macro which is used when instance logging API is used to indicate maximal log level compiled into the file. Signed-off-by: Krzysztof Chruscinski <[email protected]>
1 parent 97345db commit 5e34681

File tree

13 files changed

+223
-104
lines changed

13 files changed

+223
-104
lines changed

doc/subsystems/logging/logger.rst

+43-6
Original file line numberDiff line numberDiff line change
@@ -150,23 +150,45 @@ Logging in a module
150150
In order to use logger in the module, a unique name of a module must be
151151
specified and module must be registered with the logger core using
152152
:c:macro:`LOG_MODULE_REGISTER`. Optionally, a compile time log level for the
153-
module can be specified as well.
153+
module can be specified as the second parameter. Default log level
154+
(:option:`CONFIG_LOG_DEFAULT_LEVEL`) is used if custom log level is not
155+
provided.
154156

155157
.. code-block:: c
156158
157-
#define LOG_LEVEL CONFIG_FOO_LOG_LEVEL /* From foo module Kconfig */
158159
#include <logging/log.h>
159-
LOG_MODULE_REGISTER(foo); /* One per given log_module_name */
160+
LOG_MODULE_REGISTER(foo, CONFIG_FOO_LOG_LEVEL);
160161
161162
If the module consists of multiple files, then ``LOG_MODULE_REGISTER()`` should
162163
appear in exactly one of them. Each other file should use
163164
:c:macro:`LOG_MODULE_DECLARE` to declare its membership in the module.
165+
Optionally, a compile time log level for the module can be specified as
166+
the second parameter. Default log level (:option:`CONFIG_LOG_DEFAULT_LEVEL`)
167+
is used if custom log level is not provided.
164168

165169
.. code-block:: c
166170
167-
#define LOG_LEVEL CONFIG_FOO_LOG_LEVEL /* From foo module Kconfig */
168171
#include <logging/log.h>
169-
LOG_MODULE_DECLARE(foo); /* In all files comprising the module but one */
172+
/* In all files comprising the module but one */
173+
LOG_MODULE_DECLARE(foo, CONFIG_FOO_LOG_LEVEL);
174+
175+
In order to use logger API in a function implemented in a header file
176+
:c:macro:`LOG_MODULE_DECLARE` macro must be used in the function body
177+
before logger API is called. Optionally, a compile time log level for the module
178+
can be specified as the second parameter. Default log level
179+
(:option:`CONFIG_LOG_DEFAULT_LEVEL`) is used if custom log level is not
180+
provided.
181+
182+
.. code-block:: c
183+
184+
#include <logging/log.h>
185+
186+
static inline void foo(void)
187+
{
188+
LOG_MODULE_DECLARE(foo, CONFIG_FOO_LOG_LEVEL);
189+
190+
LOG_INF("foo");
191+
}
170192
171193
Dedicated Kconfig template (:file:`subsys/logging/Kconfig.template.log_config`)
172194
can be used to create local log level configuration.
@@ -216,15 +238,30 @@ In order to use instance level filtering following steps must be performed:
216238
Note that when logger is disabled logger instance and pointer to that instance
217239
are not created.
218240

219-
- logger can be used in function
241+
In order to use the instance logging API in a source file, a compile-time log
242+
level must be set using :c:macro:`LOG_LEVEL_SET`.
220243

221244
.. code-block:: c
222245
246+
LOG_LEVEL_SET(CONFIG_FOO_LOG_LEVEL);
247+
223248
void foo_init(foo_object *f)
224249
{
225250
LOG_INST_INF(f->log, "Initialized.");
226251
}
227252
253+
In order to use the instance logging API in a header file, a compile-time log
254+
level must be set using :c:macro:`LOG_LEVEL_SET`.
255+
256+
.. code-block:: c
257+
258+
static inline void foo_init(foo_object *f)
259+
{
260+
LOG_LEVEL_SET(CONFIG_FOO_LOG_LEVEL);
261+
262+
LOG_INST_INF(f->log, "Initialized.");
263+
}
264+
228265
Controlling the logger
229266
======================
230267

include/logging/log.h

+91-59
Original file line numberDiff line numberDiff line change
@@ -269,39 +269,47 @@ int log_printk(const char *fmt, va_list ap);
269269
*/
270270
char *log_strdup(const char *str);
271271

272-
#define __DYNAMIC_MODULE_REGISTER(_name)\
273-
struct log_source_dynamic_data LOG_ITEM_DYNAMIC_DATA(_name) \
274-
__attribute__ ((section("." STRINGIFY( \
275-
LOG_ITEM_DYNAMIC_DATA(_name)))) \
276-
) \
277-
__attribute__((used)); \
278-
static inline const struct log_source_dynamic_data * \
279-
__log_current_dynamic_data_get(void) \
280-
{ \
281-
return &LOG_ITEM_DYNAMIC_DATA(_name); \
282-
}
272+
/* Macro expects that optionally on second argument local log level is provided.
273+
* If provided it is returned, otherwise default log level is returned.
274+
*/
275+
#if defined(LOG_LEVEL) && defined(CONFIG_LOG)
276+
#define _LOG_LEVEL_RESOLVE(...) \
277+
__LOG_ARG_2(__VA_ARGS__, LOG_LEVEL)
278+
#else
279+
#define _LOG_LEVEL_RESOLVE(...) \
280+
__LOG_ARG_2(__VA_ARGS__, CONFIG_LOG_DEFAULT_LEVEL)
281+
#endif
283282

284-
#define _LOG_RUNTIME_MODULE_REGISTER(_name) \
285-
_LOG_EVAL( \
286-
CONFIG_LOG_RUNTIME_FILTERING, \
287-
(; __DYNAMIC_MODULE_REGISTER(_name)), \
288-
() \
289-
)
283+
/* Return first argument */
284+
#define _LOG_ARG1(arg1, ...) arg1
290285

291-
#define _LOG_MODULE_REGISTER(_name, _level) \
286+
287+
#define _LOG_MODULE_CONST_DATA_CREATE(_name, _level) \
292288
const struct log_source_const_data LOG_ITEM_CONST_DATA(_name) \
293289
__attribute__ ((section("." STRINGIFY(LOG_ITEM_CONST_DATA(_name))))) \
294290
__attribute__((used)) = { \
295291
.name = STRINGIFY(_name), \
296292
.level = _level \
297-
} \
298-
_LOG_RUNTIME_MODULE_REGISTER(_name); \
299-
static inline const struct log_source_const_data * \
300-
__log_current_const_data_get(void) \
301-
{ \
302-
return &LOG_ITEM_CONST_DATA(_name); \
303293
}
304294

295+
#define _LOG_MODULE_DYNAMIC_DATA_CREATE(_name) \
296+
struct log_source_dynamic_data LOG_ITEM_DYNAMIC_DATA(_name) \
297+
__attribute__ ((section("." STRINGIFY( \
298+
LOG_ITEM_DYNAMIC_DATA(_name)))) \
299+
) \
300+
__attribute__((used))
301+
302+
#define _LOG_MODULE_DYNAMIC_DATA_COND_CREATE(_name) \
303+
_LOG_EVAL( \
304+
IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING), \
305+
(_LOG_MODULE_DYNAMIC_DATA_CREATE(_name);), \
306+
() \
307+
)
308+
309+
#define _LOG_MODULE_DATA_CREATE(_name, _level) \
310+
_LOG_MODULE_CONST_DATA_CREATE(_name, _level); \
311+
_LOG_MODULE_DYNAMIC_DATA_COND_CREATE(_name)
312+
305313
/**
306314
* @brief Create module-specific state and register the module with Logger.
307315
*
@@ -313,44 +321,36 @@ char *log_strdup(const char *str);
313321
* - The module consists of more than one file, and another file
314322
* invokes this macro. (LOG_MODULE_DECLARE() should be used instead
315323
* in all of the module's other files.)
316-
* - Instance logging is used and there is no need to create module entry.
324+
* - Instance logging is used and there is no need to create module entry. In
325+
* that case LOG_LEVEL_SET() should be used to set log level used within the
326+
* file.
327+
*
328+
* Macro accepts one or two parameters:
329+
* - module name
330+
* - optional log level. If not provided then default log level is used in
331+
* the file.
332+
*
333+
* Example usage:
334+
* - LOG_MODULE_REGISTER(foo, CONFIG_FOO_LOG_LEVEL)
335+
* - LOG_MODULE_REGISTER(foo)
336+
*
317337
*
318338
* @note The module's state is defined, and the module is registered,
319339
* only if LOG_LEVEL for the current source file is non-zero or
320340
* it is not defined and CONFIG_LOG_DEFAULT_LOG_LEVEL is non-zero.
321341
* In other cases, this macro has no effect.
322342
* @see LOG_MODULE_DECLARE
323343
*/
324-
#define LOG_MODULE_REGISTER(log_module_name) \
325-
_LOG_EVAL( \
326-
_LOG_LEVEL(), \
327-
(_LOG_MODULE_REGISTER(log_module_name, _LOG_LEVEL())), \
328-
()/*Empty*/ \
329-
)
330-
331-
#define __DYNAMIC_MODULE_DECLARE(_name) \
332-
extern struct log_source_dynamic_data LOG_ITEM_DYNAMIC_DATA(_name);\
333-
static inline struct log_source_dynamic_data * \
334-
__log_current_dynamic_data_get(void) \
335-
{ \
336-
return &LOG_ITEM_DYNAMIC_DATA(_name); \
337-
}
338344

339-
#define _LOG_RUNTIME_MODULE_DECLARE(_name) \
340-
_LOG_EVAL( \
341-
CONFIG_LOG_RUNTIME_FILTERING, \
342-
(; __DYNAMIC_MODULE_DECLARE(_name)), \
343-
() \
344-
)
345345

346-
#define _LOG_MODULE_DECLARE(_name, _level) \
347-
extern const struct log_source_const_data LOG_ITEM_CONST_DATA(_name) \
348-
_LOG_RUNTIME_MODULE_DECLARE(_name); \
349-
static inline const struct log_source_const_data * \
350-
__log_current_const_data_get(void) \
351-
{ \
352-
return &LOG_ITEM_CONST_DATA(_name); \
353-
}
346+
#define LOG_MODULE_REGISTER(...) \
347+
_LOG_EVAL( \
348+
_LOG_LEVEL_RESOLVE(__VA_ARGS__), \
349+
(_LOG_MODULE_DATA_CREATE(_LOG_ARG1(__VA_ARGS__), \
350+
_LOG_LEVEL_RESOLVE(__VA_ARGS__))),\
351+
()/*Empty*/ \
352+
) \
353+
LOG_MODULE_DECLARE(__VA_ARGS__)
354354

355355
/**
356356
* @brief Macro for declaring a log module (not registering it).
@@ -363,18 +363,50 @@ char *log_strdup(const char *str);
363363
* declare that same state. (Otherwise, LOG_INF() etc. will not be
364364
* able to refer to module-specific state variables.)
365365
*
366+
* Macro accepts one or two parameters:
367+
* - module name
368+
* - optional log level. If not provided then default log level is used in
369+
* the file.
370+
*
371+
* Example usage:
372+
* - LOG_MODULE_DECLARE(foo, CONFIG_FOO_LOG_LEVEL)
373+
* - LOG_MODULE_DECLARE(foo)
374+
*
366375
* @note The module's state is declared only if LOG_LEVEL for the
367376
* current source file is non-zero or it is not defined and
368377
* CONFIG_LOG_DEFAULT_LOG_LEVEL is non-zero. In other cases,
369378
* this macro has no effect.
370379
* @see LOG_MODULE_REGISTER
371380
*/
372-
#define LOG_MODULE_DECLARE(log_module_name) \
373-
_LOG_EVAL( \
374-
_LOG_LEVEL(), \
375-
(_LOG_MODULE_DECLARE(log_module_name, _LOG_LEVEL())), \
376-
() \
377-
) \
381+
#define LOG_MODULE_DECLARE(...) \
382+
extern const struct log_source_const_data \
383+
LOG_ITEM_CONST_DATA(_LOG_ARG1(__VA_ARGS__)); \
384+
extern struct log_source_dynamic_data \
385+
LOG_ITEM_DYNAMIC_DATA(_LOG_ARG1(__VA_ARGS__)); \
386+
\
387+
static const struct log_source_const_data * \
388+
__log_current_const_data __attribute__((unused)) = \
389+
_LOG_LEVEL_RESOLVE(__VA_ARGS__) ? \
390+
&LOG_ITEM_CONST_DATA(_LOG_ARG1(__VA_ARGS__)) : NULL; \
391+
\
392+
static struct log_source_dynamic_data * \
393+
__log_current_dynamic_data __attribute__((unused)) = \
394+
(_LOG_LEVEL_RESOLVE(__VA_ARGS__) && \
395+
IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) ? \
396+
&LOG_ITEM_DYNAMIC_DATA(_LOG_ARG1(__VA_ARGS__)) : NULL;\
397+
\
398+
static const u32_t __log_level __attribute__((unused)) = \
399+
_LOG_LEVEL_RESOLVE(__VA_ARGS__)
400+
401+
/**
402+
* @brief Macro for setting log level in the file or function where instance
403+
* logging API is used.
404+
*
405+
* @param level Level used in file or in function.
406+
*
407+
*/
408+
#define LOG_LEVEL_SET(level) \
409+
static const u32_t __log_level __attribute__((unused)) = level
378410

379411
/**
380412
* @}

include/logging/log_core.h

+20-25
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ extern "C" {
5555
/**
5656
* @brief Macro for conditional code generation if provided log level allows.
5757
*
58-
* Macro behaves similarly to standard #if #else #endif clause. The difference is
59-
* that it is evaluated when used and not when header file is included.
58+
* Macro behaves similarly to standard #if #else #endif clause. The difference
59+
* is that it is evaluated when used and not when header file is included.
6060
*
6161
* @param _eval_level Evaluated level. If level evaluates to one of existing log
6262
* log level (1-4) then macro evaluates to _iftrue.
@@ -112,44 +112,39 @@ extern "C" {
112112
*
113113
* @param _addr Address of the element.
114114
*/
115-
#define LOG_CONST_ID_GET(_addr) \
116-
_LOG_EVAL( \
117-
_LOG_LEVEL(), \
118-
(log_const_source_id((const struct log_source_const_data *)_addr)), \
119-
(0) \
115+
#define LOG_CONST_ID_GET(_addr) \
116+
_LOG_EVAL(\
117+
CONFIG_LOG,\
118+
(__log_level ? \
119+
log_const_source_id((const struct log_source_const_data *)_addr) : \
120+
0),\
121+
(0)\
120122
)
121123

122124
/**
123125
* @def LOG_CURRENT_MODULE_ID
124126
* @brief Macro for getting ID of current module.
125127
*/
126-
#define LOG_CURRENT_MODULE_ID() \
127-
_LOG_EVAL( \
128-
_LOG_LEVEL(), \
129-
(log_const_source_id(__log_current_const_data_get())), \
130-
(0) \
131-
)
128+
#define LOG_CURRENT_MODULE_ID() (__log_level ? \
129+
log_const_source_id(__log_current_const_data) : 0)
132130

133131
/**
134132
* @def LOG_CURRENT_DYNAMIC_DATA_ADDR
135133
* @brief Macro for getting address of dynamic structure of current module.
136134
*/
137-
#define LOG_CURRENT_DYNAMIC_DATA_ADDR() \
138-
_LOG_EVAL( \
139-
_LOG_LEVEL(), \
140-
(__log_current_dynamic_data_get()), \
141-
((struct log_source_dynamic_data *)0) \
142-
)
135+
#define LOG_CURRENT_DYNAMIC_DATA_ADDR() (__log_level ? \
136+
__log_current_dynamic_data : (struct log_source_dynamic_data *)0)
143137

144138
/** @brief Macro for getting ID of the element of the section.
145139
*
146140
* @param _addr Address of the element.
147141
*/
148-
#define LOG_DYNAMIC_ID_GET(_addr) \
149-
_LOG_EVAL( \
150-
_LOG_LEVEL(), \
151-
(log_dynamic_source_id((struct log_source_dynamic_data *)_addr)), \
152-
(0) \
142+
#define LOG_DYNAMIC_ID_GET(_addr) \
143+
_LOG_EVAL(\
144+
CONFIG_LOG,\
145+
(__log_level ? \
146+
log_dynamic_source_id((struct log_source_dynamic_data *)_addr) : 0),\
147+
(0)\
153148
)
154149

155150
/**
@@ -230,7 +225,7 @@ extern "C" {
230225
_LOG_LEVEL_CHECK(_level, CONFIG_LOG_OVERRIDE_LEVEL, LOG_LEVEL_NONE) \
231226
|| \
232227
(!IS_ENABLED(CONFIG_LOG_OVERRIDE_LEVEL) && \
233-
_LOG_LEVEL_CHECK(_level, LOG_LEVEL, CONFIG_LOG_DEFAULT_LEVEL) && \
228+
(_level <= __log_level) && \
234229
(_level <= CONFIG_LOG_MAX_LEVEL) \
235230
) \
236231
))

samples/subsys/logging/logger/src/main.c

+7
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static void module_logging_showcase(void)
8181
printk("Module logging showcase.\n");
8282

8383
sample_module_func();
84+
inline_func();
8485

8586
if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
8687
printk("Disabling logging in the %s module\n",
@@ -111,7 +112,9 @@ static void instance_logging_showcase(void)
111112
{
112113
printk("Instance level logging showcase.\n");
113114

115+
sample_instance_inline_call(&inst1);
114116
sample_instance_call(&inst1);
117+
sample_instance_inline_call(&inst2);
115118
sample_instance_call(&inst2);
116119

117120
if (IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) {
@@ -121,7 +124,9 @@ static void instance_logging_showcase(void)
121124
log_filter_set(NULL, 0,
122125
log_source_id_get(INST1_NAME), LOG_LEVEL_WRN);
123126

127+
sample_instance_inline_call(&inst1);
124128
sample_instance_call(&inst1);
129+
sample_instance_inline_call(&inst2);
125130
sample_instance_call(&inst2);
126131

127132
printk("Disabling logging on both instances.\n");
@@ -134,7 +139,9 @@ static void instance_logging_showcase(void)
134139
log_source_id_get(INST2_NAME),
135140
LOG_LEVEL_NONE);
136141

142+
sample_instance_inline_call(&inst1);
137143
sample_instance_call(&inst1);
144+
sample_instance_inline_call(&inst2);
138145
sample_instance_call(&inst2);
139146

140147
printk("Function call on both instances with logging disabled.\n");

0 commit comments

Comments
 (0)