Zephyr API Documentation 4.2.99
A Scalable Open Source RTOS
 4.2.99
log.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_H_
8#define ZEPHYR_INCLUDE_LOGGING_LOG_H_
9
13#include <zephyr/sys/atomic.h>
15
16#if CONFIG_USERSPACE && CONFIG_LOG_ALWAYS_RUNTIME
18#endif
19
20#ifdef CONFIG_LOG_RATELIMIT
21#include <zephyr/kernel.h>
22#endif
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28#ifdef CONFIG_LOG_RATELIMIT
29#define LOG_RATELIMIT_INTERVAL_MS CONFIG_LOG_RATELIMIT_INTERVAL_MS
30
31#else
32#define LOG_RATELIMIT_INTERVAL_MS 0
33
34#endif
35
45
52
62#define LOG_ERR(...) Z_LOG(LOG_LEVEL_ERR, __VA_ARGS__)
63
73#define LOG_WRN(...) Z_LOG(LOG_LEVEL_WRN, __VA_ARGS__)
74
83#define LOG_INF(...) Z_LOG(LOG_LEVEL_INF, __VA_ARGS__)
84
93#define LOG_DBG(...) Z_LOG(LOG_LEVEL_DBG, __VA_ARGS__)
94
104#define LOG_WRN_ONCE(...) \
105 do { \
106 static atomic_t __warned; \
107 if (unlikely(atomic_cas(&__warned, 0, 1))) { \
108 Z_LOG(LOG_LEVEL_WRN, __VA_ARGS__); \
109 } \
110 } while (0)
111
124#define _LOG_RATELIMIT_CORE(_level, _rate_ms, ...) \
125 do { \
126 static atomic_t __last_log_time; \
127 static atomic_t __skipped_count; \
128 uint32_t __now = k_uptime_get_32(); \
129 uint32_t __last = atomic_get(&__last_log_time); \
130 uint32_t __diff = __now - __last; \
131 if (unlikely(__diff >= (_rate_ms))) { \
132 if (atomic_cas(&__last_log_time, __last, __now)) { \
133 uint32_t __skipped = atomic_clear(&__skipped_count); \
134 if (__skipped > 0) { \
135 Z_LOG(_level, "Skipped %d messages", __skipped); \
136 } \
137 Z_LOG(_level, __VA_ARGS__); \
138 } else { \
139 atomic_inc(&__skipped_count); \
140 } \
141 } else { \
142 atomic_inc(&__skipped_count); \
143 } \
144 } while (0)
145
161
173#define _LOG_RATELIMIT_LVL(_level, _rate_ms, ...) \
174 do { \
175 if (IS_ENABLED(CONFIG_LOG_RATELIMIT)) { \
176 _LOG_RATELIMIT_CORE(_level, _rate_ms, __VA_ARGS__); \
177 } else if (IS_ENABLED(CONFIG_LOG_RATELIMIT_FALLBACK_DROP)) { \
178 (void)0; \
179 } else { \
180 Z_LOG(_level, __VA_ARGS__); \
181 } \
182 } while (0)
183
194#define LOG_WRN_RATELIMIT(...) \
195 _LOG_RATELIMIT_LVL(LOG_LEVEL_WRN, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
196
208#define LOG_ERR_RATELIMIT(...) \
209 _LOG_RATELIMIT_LVL(LOG_LEVEL_ERR, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
210
221#define LOG_INF_RATELIMIT(...) \
222 _LOG_RATELIMIT_LVL(LOG_LEVEL_INF, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
223
234#define LOG_DBG_RATELIMIT(...) \
235 _LOG_RATELIMIT_LVL(LOG_LEVEL_DBG, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
236
251#define _LOG_HEXDUMP_RATELIMIT_CORE(_level, _rate_ms, _data, _length, _str) \
252 do { \
253 static atomic_t __last_log_time; \
254 static atomic_t __skipped_count; \
255 uint32_t __now = k_uptime_get_32(); \
256 uint32_t __last = atomic_get(&__last_log_time); \
257 uint32_t __diff = __now - __last; \
258 if (unlikely(__diff >= (_rate_ms))) { \
259 if (atomic_cas(&__last_log_time, __last, __now)) { \
260 uint32_t __skipped = atomic_clear(&__skipped_count); \
261 if (__skipped > 0) { \
262 Z_LOG(_level, "Skipped %d hexdump messages", __skipped); \
263 } \
264 Z_LOG_HEXDUMP(_level, _data, _length, _str); \
265 } else { \
266 atomic_inc(&__skipped_count); \
267 } \
268 } else { \
269 atomic_inc(&__skipped_count); \
270 } \
271 } while (0)
272
286#define _LOG_HEXDUMP_RATELIMIT_LVL(_level, _rate_ms, _data, _length, _str) \
287 do { \
288 if (IS_ENABLED(CONFIG_LOG_RATELIMIT)) { \
289 _LOG_HEXDUMP_RATELIMIT_CORE(_level, _rate_ms, _data, _length, _str); \
290 } else if (IS_ENABLED(CONFIG_LOG_RATELIMIT_FALLBACK_DROP)) { \
291 (void)0; \
292 } else { \
293 Z_LOG_HEXDUMP(_level, _data, _length, _str); \
294 } \
295 } while (0)
296
309#define LOG_HEXDUMP_ERR_RATELIMIT(_data, _length, _str) \
310 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_ERR, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
311
324#define LOG_HEXDUMP_WRN_RATELIMIT(_data, _length, _str) \
325 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_WRN, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
326
338#define LOG_HEXDUMP_INF_RATELIMIT(_data, _length, _str) \
339 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_INF, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
340
352#define LOG_HEXDUMP_DBG_RATELIMIT(_data, _length, _str) \
353 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_DBG, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
354
362
374#define LOG_ERR_RATELIMIT_RATE(_rate_ms, ...) \
375 _LOG_RATELIMIT_LVL(LOG_LEVEL_ERR, _rate_ms, __VA_ARGS__)
376
388#define LOG_WRN_RATELIMIT_RATE(_rate_ms, ...) \
389 _LOG_RATELIMIT_LVL(LOG_LEVEL_WRN, _rate_ms, __VA_ARGS__)
390
402#define LOG_INF_RATELIMIT_RATE(_rate_ms, ...) \
403 _LOG_RATELIMIT_LVL(LOG_LEVEL_INF, _rate_ms, __VA_ARGS__)
404
416#define LOG_DBG_RATELIMIT_RATE(_rate_ms, ...) \
417 _LOG_RATELIMIT_LVL(LOG_LEVEL_DBG, _rate_ms, __VA_ARGS__)
418
431#define LOG_HEXDUMP_ERR_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
432 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_ERR, _rate_ms, _data, _length, _str)
433
446#define LOG_HEXDUMP_WRN_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
447 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_WRN, _rate_ms, _data, _length, _str)
448
461#define LOG_HEXDUMP_INF_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
462 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_INF, _rate_ms, _data, _length, _str)
463
476#define LOG_HEXDUMP_DBG_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
477 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_DBG, _rate_ms, _data, _length, _str)
478
488#define LOG_PRINTK(...) Z_LOG_PRINTK(0, __VA_ARGS__)
489
498#define LOG_RAW(...) Z_LOG_PRINTK(1, __VA_ARGS__)
499
512#define LOG_INST_ERR(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_ERR, _log_inst, __VA_ARGS__)
513
527#define LOG_INST_WRN(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_WRN, _log_inst, __VA_ARGS__)
528
541#define LOG_INST_INF(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_INF, _log_inst, __VA_ARGS__)
542
555#define LOG_INST_DBG(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_DBG, _log_inst, __VA_ARGS__)
556
567#define LOG_HEXDUMP_ERR(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_ERR, _data, _length, (_str))
568
579#define LOG_HEXDUMP_WRN(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_WRN, _data, _length, (_str))
580
590#define LOG_HEXDUMP_INF(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_INF, _data, _length, (_str))
591
601#define LOG_HEXDUMP_DBG(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_DBG, _data, _length, (_str))
602
617#define LOG_INST_HEXDUMP_ERR(_log_inst, _data, _length, _str) \
618 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_ERR, _log_inst, _data, _length, _str)
619
632#define LOG_INST_HEXDUMP_WRN(_log_inst, _data, _length, _str) \
633 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_WRN, _log_inst, _data, _length, _str)
634
646#define LOG_INST_HEXDUMP_INF(_log_inst, _data, _length, _str) \
647 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_INF, _log_inst, _data, _length, _str)
648
660#define LOG_INST_HEXDUMP_DBG(_log_inst, _data, _length, _str) \
661 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_DBG, _log_inst, _data, _length, _str)
662
675void z_log_vprintk(const char *fmt, va_list ap);
676
677#ifdef __cplusplus
678}
679#define LOG_IN_CPLUSPLUS 1
680#endif
681/* Macro expects that optionally on second argument local log level is provided.
682 * If provided it is returned, otherwise default log level is returned or
683 * LOG_LEVEL, if it was locally defined.
684 */
685#if !defined(CONFIG_LOG)
686#define _LOG_LEVEL_RESOLVE(...) LOG_LEVEL_NONE
687#else
688#define _LOG_LEVEL_RESOLVE(...) \
689 Z_LOG_EVAL(COND_CODE_0(LOG_LEVEL, (1), (LOG_LEVEL)), \
690 (GET_ARG_N(2, __VA_ARGS__, LOG_LEVEL)), \
691 (GET_ARG_N(2, __VA_ARGS__, CONFIG_LOG_DEFAULT_LEVEL)))
692#endif
693
694/* Return first argument */
695#define _LOG_ARG1(arg1, ...) arg1
696
697#define _LOG_MODULE_CONST_DATA_CREATE(_name, _level) \
698 IF_ENABLED(CONFIG_LOG_FMT_SECTION, ( \
699 static const char UTIL_CAT(_name, _str)[] \
700 __in_section(_log_strings, static, _CONCAT(_name, _)) __used __noasan = \
701 STRINGIFY(_name);)) \
702 IF_ENABLED(LOG_IN_CPLUSPLUS, (extern)) \
703 const STRUCT_SECTION_ITERABLE_ALTERNATE(log_const, log_source_const_data, \
704 Z_LOG_ITEM_CONST_DATA(_name)) = { \
705 .name = COND_CODE_1(CONFIG_LOG_FMT_SECTION, \
706 (UTIL_CAT(_name, _str)), (STRINGIFY(_name))), .level = (_level)}
707
708#define _LOG_MODULE_DYNAMIC_DATA_CREATE(_name) \
709 STRUCT_SECTION_ITERABLE_ALTERNATE(log_dynamic, log_source_dynamic_data, \
710 LOG_ITEM_DYNAMIC_DATA(_name))
711
712#define _LOG_MODULE_DYNAMIC_DATA_COND_CREATE(_name) \
713 IF_ENABLED(CONFIG_LOG_RUNTIME_FILTERING, \
714 (_LOG_MODULE_DYNAMIC_DATA_CREATE(_name);))
715
716#define _LOG_MODULE_DATA_CREATE(_name, _level) \
717 _LOG_MODULE_CONST_DATA_CREATE(_name, _level); \
718 _LOG_MODULE_DYNAMIC_DATA_COND_CREATE(_name)
719
720/* Determine if data for the module shall be created. It is created if logging
721 * is enabled, override level is set or module specific level is set (not off).
722 */
723#define Z_DO_LOG_MODULE_REGISTER(...) \
724 COND_CODE_1(CONFIG_LOG, \
725 (Z_LOG_EVAL(CONFIG_LOG_OVERRIDE_LEVEL, \
726 (1), \
727 (Z_LOG_EVAL(_LOG_LEVEL_RESOLVE(__VA_ARGS__), (1), (0))) \
728 )), (0))
729
730/* Determine if the data of the log module shall be in the partition
731 * 'k_log_partition' to allow a user mode thread access to this data.
732 */
733#if CONFIG_USERSPACE && CONFIG_LOG_ALWAYS_RUNTIME
734extern struct k_mem_partition k_log_partition;
735#define Z_LOG_MODULE_PARTITION(_k_app_mem) _k_app_mem(k_log_partition)
736#else
737#define Z_LOG_MODULE_PARTITION(_k_app_mem)
738#endif
739
771#define LOG_MODULE_REGISTER(...) \
772 COND_CODE_1( \
773 Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__), \
774 (_LOG_MODULE_DATA_CREATE(GET_ARG_N(1, __VA_ARGS__), \
775 _LOG_LEVEL_RESOLVE(__VA_ARGS__))),\
776 () \
777 ) \
778 LOG_MODULE_DECLARE(__VA_ARGS__)
779
806#define LOG_MODULE_DECLARE(...) \
807 extern const struct log_source_const_data Z_LOG_ITEM_CONST_DATA( \
808 GET_ARG_N(1, __VA_ARGS__)); \
809 extern struct log_source_dynamic_data LOG_ITEM_DYNAMIC_DATA(GET_ARG_N(1, __VA_ARGS__)); \
810 \
811 Z_LOG_MODULE_PARTITION(K_APP_DMEM) \
812 static const struct log_source_const_data *__log_current_const_data __unused = \
813 Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__) \
814 ? &Z_LOG_ITEM_CONST_DATA(GET_ARG_N(1, __VA_ARGS__)) \
815 : NULL; \
816 \
817 Z_LOG_MODULE_PARTITION(K_APP_DMEM) \
818 static struct log_source_dynamic_data *__log_current_dynamic_data __unused = \
819 (Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__) && \
820 IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) \
821 ? &LOG_ITEM_DYNAMIC_DATA(GET_ARG_N(1, __VA_ARGS__)) \
822 : NULL; \
823 \
824 Z_LOG_MODULE_PARTITION(K_APP_BMEM) \
825 static const uint32_t __log_level __unused = _LOG_LEVEL_RESOLVE(__VA_ARGS__)
826
834#define LOG_LEVEL_SET(level) \
835 static const uint32_t __log_level __unused = Z_LOG_RESOLVED_LEVEL(level, 0)
836
837#ifdef CONFIG_LOG_CUSTOM_HEADER
838/* This include must always be at the end of log.h */
839#include <zephyr_custom_log.h>
840#endif
841
842/*
843 * Eclipse CDT or JetBrains Clion parser is sometimes confused by logging API
844 * code and freezes the whole IDE. Following lines hides LOG_x macros from them.
845 */
846#if defined(__CDT_PARSER__) || defined(__JETBRAINS_IDE__)
847#undef LOG_ERR
848#undef LOG_WRN
849#undef LOG_INF
850#undef LOG_DBG
851
852#undef LOG_HEXDUMP_ERR
853#undef LOG_HEXDUMP_WRN
854#undef LOG_HEXDUMP_INF
855#undef LOG_HEXDUMP_DBG
856
857#define LOG_ERR(...) (void)0
858#define LOG_WRN(...) (void)0
859#define LOG_DBG(...) (void)0
860#define LOG_INF(...) (void)0
861
862#define LOG_HEXDUMP_ERR(...) (void)0
863#define LOG_HEXDUMP_WRN(...) (void)0
864#define LOG_HEXDUMP_DBG(...) (void)0
865#define LOG_HEXDUMP_INF(...) (void)0
866
867#undef LOG_ERR_RATELIMIT
868#undef LOG_WRN_RATELIMIT
869#undef LOG_INF_RATELIMIT
870#undef LOG_DBG_RATELIMIT
871
872#undef LOG_ERR_RATELIMIT_RATE
873#undef LOG_WRN_RATELIMIT_RATE
874#undef LOG_INF_RATELIMIT_RATE
875#undef LOG_DBG_RATELIMIT_RATE
876
877#undef LOG_HEXDUMP_ERR_RATELIMIT
878#undef LOG_HEXDUMP_WRN_RATELIMIT
879#undef LOG_HEXDUMP_INF_RATELIMIT
880#undef LOG_HEXDUMP_DBG_RATELIMIT
881
882#undef LOG_HEXDUMP_ERR_RATELIMIT_RATE
883#undef LOG_HEXDUMP_WRN_RATELIMIT_RATE
884#undef LOG_HEXDUMP_INF_RATELIMIT_RATE
885#undef LOG_HEXDUMP_DBG_RATELIMIT_RATE
886
887#define LOG_ERR_RATELIMIT(...) (void)0
888#define LOG_WRN_RATELIMIT(...) (void)0
889#define LOG_INF_RATELIMIT(...) (void)0
890#define LOG_DBG_RATELIMIT(...) (void)0
891
892#define LOG_HEXDUMP_ERR_RATELIMIT(...) (void)0
893#define LOG_HEXDUMP_WRN_RATELIMIT(...) (void)0
894#define LOG_HEXDUMP_INF_RATELIMIT(...) (void)0
895#define LOG_HEXDUMP_DBG_RATELIMIT(...) (void)0
896
897#define LOG_ERR_RATELIMIT_RATE(...) (void)0
898#define LOG_WRN_RATELIMIT_RATE(...) (void)0
899#define LOG_INF_RATELIMIT_RATE(...) (void)0
900#define LOG_DBG_RATELIMIT_RATE(...) (void)0
901
902#define LOG_HEXDUMP_ERR_RATELIMIT_RATE(...) (void)0
903#define LOG_HEXDUMP_WRN_RATELIMIT_RATE(...) (void)0
904#define LOG_HEXDUMP_INF_RATELIMIT_RATE(...) (void)0
905#define LOG_HEXDUMP_DBG_RATELIMIT_RATE(...) (void)0
906#endif
907
911
912#endif /* ZEPHYR_INCLUDE_LOGGING_LOG_H_ */
Public kernel APIs.
Memory Partition.
Definition mem_domain.h:55
Macro utilities.