Zephyr Project API 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
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
12
13#ifndef ZEPHYR_INCLUDE_LOGGING_LOG_H_
14#define ZEPHYR_INCLUDE_LOGGING_LOG_H_
15
19#include <zephyr/sys/atomic.h>
21
22#if defined(CONFIG_USERSPACE) && defined(CONFIG_LOG_ALWAYS_RUNTIME)
24#endif
25
26#ifdef CONFIG_LOG_RATELIMIT
27#include <zephyr/kernel.h>
28#endif
29
30#ifdef __cplusplus
31extern "C" {
32#endif
33
43
50
55
65#define LOG_ERR(...) Z_LOG(LOG_LEVEL_ERR, __VA_ARGS__)
66
76#define LOG_WRN(...) Z_LOG(LOG_LEVEL_WRN, __VA_ARGS__)
77
86#define LOG_INF(...) Z_LOG(LOG_LEVEL_INF, __VA_ARGS__)
87
96#define LOG_DBG(...) Z_LOG(LOG_LEVEL_DBG, __VA_ARGS__)
97
107#define LOG_WRN_ONCE(...) \
108 do { \
109 static atomic_t __warned; \
110 if (unlikely(atomic_cas(&__warned, 0, 1))) { \
111 Z_LOG(LOG_LEVEL_WRN, __VA_ARGS__); \
112 } \
113 } while (0)
114
116
128
137#ifdef CONFIG_LOG_RATELIMIT
138#define LOG_RATELIMIT_INTERVAL_MS CONFIG_LOG_RATELIMIT_INTERVAL_MS
139#else
140#define LOG_RATELIMIT_INTERVAL_MS 0
141#endif
142
155#define _LOG_RATELIMIT_CORE(_level, _rate_ms, ...) \
156 do { \
157 if (Z_LOG_CONST_LEVEL_CHECK(_level)) { \
158 static atomic_t __last_log_time; \
159 static atomic_t __skipped_count; \
160 uint32_t __now = k_uptime_get_32(); \
161 uint32_t __last = atomic_get(&__last_log_time); \
162 uint32_t __diff = __now - __last; \
163 if (unlikely(__diff >= (_rate_ms))) { \
164 if (atomic_cas(&__last_log_time, __last, __now)) { \
165 uint32_t __skipped = atomic_clear(&__skipped_count); \
166 if (__skipped > 0) { \
167 Z_LOG(_level, "Skipped %d messages", __skipped); \
168 } \
169 Z_LOG(_level, __VA_ARGS__); \
170 } else { \
171 atomic_inc(&__skipped_count); \
172 } \
173 } else { \
174 atomic_inc(&__skipped_count); \
175 } \
176 } \
177 } while (0)
178
190#define _LOG_RATELIMIT_LVL(_level, _rate_ms, ...) \
191 do { \
192 if (IS_ENABLED(CONFIG_LOG_RATELIMIT)) { \
193 _LOG_RATELIMIT_CORE(_level, _rate_ms, __VA_ARGS__); \
194 } else if (IS_ENABLED(CONFIG_LOG_RATELIMIT_FALLBACK_DROP)) { \
195 (void)0; \
196 } else { \
197 Z_LOG(_level, __VA_ARGS__); \
198 } \
199 } while (0)
200
211#define LOG_WRN_RATELIMIT(...) \
212 _LOG_RATELIMIT_LVL(LOG_LEVEL_WRN, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
213
225#define LOG_ERR_RATELIMIT(...) \
226 _LOG_RATELIMIT_LVL(LOG_LEVEL_ERR, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
227
238#define LOG_INF_RATELIMIT(...) \
239 _LOG_RATELIMIT_LVL(LOG_LEVEL_INF, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
240
251#define LOG_DBG_RATELIMIT(...) \
252 _LOG_RATELIMIT_LVL(LOG_LEVEL_DBG, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
253
268#define _LOG_HEXDUMP_RATELIMIT_CORE(_level, _rate_ms, _data, _length, _str) \
269 do { \
270 if (Z_LOG_CONST_LEVEL_CHECK(_level)) { \
271 static atomic_t __last_log_time; \
272 static atomic_t __skipped_count; \
273 uint32_t __now = k_uptime_get_32(); \
274 uint32_t __last = atomic_get(&__last_log_time); \
275 uint32_t __diff = __now - __last; \
276 if (unlikely(__diff >= (_rate_ms))) { \
277 if (atomic_cas(&__last_log_time, __last, __now)) { \
278 uint32_t __skipped = atomic_clear(&__skipped_count); \
279 if (__skipped > 0) { \
280 Z_LOG(_level, "Skipped %d hexdump messages", \
281 __skipped); \
282 } \
283 Z_LOG_HEXDUMP(_level, _data, _length, _str); \
284 } else { \
285 atomic_inc(&__skipped_count); \
286 } \
287 } else { \
288 atomic_inc(&__skipped_count); \
289 } \
290 } \
291 } while (0)
292
306#define _LOG_HEXDUMP_RATELIMIT_LVL(_level, _rate_ms, _data, _length, _str) \
307 do { \
308 if (IS_ENABLED(CONFIG_LOG_RATELIMIT)) { \
309 _LOG_HEXDUMP_RATELIMIT_CORE(_level, _rate_ms, _data, _length, _str); \
310 } else if (IS_ENABLED(CONFIG_LOG_RATELIMIT_FALLBACK_DROP)) { \
311 (void)0; \
312 } else { \
313 Z_LOG_HEXDUMP(_level, _data, _length, _str); \
314 } \
315 } while (0)
316
329#define LOG_HEXDUMP_ERR_RATELIMIT(_data, _length, _str) \
330 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_ERR, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
331
344#define LOG_HEXDUMP_WRN_RATELIMIT(_data, _length, _str) \
345 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_WRN, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
346
358#define LOG_HEXDUMP_INF_RATELIMIT(_data, _length, _str) \
359 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_INF, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
360
372#define LOG_HEXDUMP_DBG_RATELIMIT(_data, _length, _str) \
373 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_DBG, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
374
386#define LOG_ERR_RATELIMIT_RATE(_rate_ms, ...) \
387 _LOG_RATELIMIT_LVL(LOG_LEVEL_ERR, _rate_ms, __VA_ARGS__)
388
400#define LOG_WRN_RATELIMIT_RATE(_rate_ms, ...) \
401 _LOG_RATELIMIT_LVL(LOG_LEVEL_WRN, _rate_ms, __VA_ARGS__)
402
414#define LOG_INF_RATELIMIT_RATE(_rate_ms, ...) \
415 _LOG_RATELIMIT_LVL(LOG_LEVEL_INF, _rate_ms, __VA_ARGS__)
416
428#define LOG_DBG_RATELIMIT_RATE(_rate_ms, ...) \
429 _LOG_RATELIMIT_LVL(LOG_LEVEL_DBG, _rate_ms, __VA_ARGS__)
430
443#define LOG_HEXDUMP_ERR_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
444 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_ERR, _rate_ms, _data, _length, _str)
445
458#define LOG_HEXDUMP_WRN_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
459 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_WRN, _rate_ms, _data, _length, _str)
460
473#define LOG_HEXDUMP_INF_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
474 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_INF, _rate_ms, _data, _length, _str)
475
488#define LOG_HEXDUMP_DBG_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
489 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_DBG, _rate_ms, _data, _length, _str)
490
492
497
507#define LOG_PRINTK(...) Z_LOG_PRINTK(0, __VA_ARGS__)
508
517#define LOG_RAW(...) Z_LOG_PRINTK(1, __VA_ARGS__)
518
520
525
538#define LOG_INST_ERR(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_ERR, _log_inst, __VA_ARGS__)
539
553#define LOG_INST_WRN(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_WRN, _log_inst, __VA_ARGS__)
554
567#define LOG_INST_INF(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_INF, _log_inst, __VA_ARGS__)
568
581#define LOG_INST_DBG(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_DBG, _log_inst, __VA_ARGS__)
582
584
589
600#define LOG_HEXDUMP_ERR(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_ERR, _data, _length, (_str))
601
612#define LOG_HEXDUMP_WRN(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_WRN, _data, _length, (_str))
613
623#define LOG_HEXDUMP_INF(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_INF, _data, _length, (_str))
624
634#define LOG_HEXDUMP_DBG(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_DBG, _data, _length, (_str))
635
637
642
657#define LOG_INST_HEXDUMP_ERR(_log_inst, _data, _length, _str) \
658 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_ERR, _log_inst, _data, _length, _str)
659
672#define LOG_INST_HEXDUMP_WRN(_log_inst, _data, _length, _str) \
673 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_WRN, _log_inst, _data, _length, _str)
674
686#define LOG_INST_HEXDUMP_INF(_log_inst, _data, _length, _str) \
687 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_INF, _log_inst, _data, _length, _str)
688
700#define LOG_INST_HEXDUMP_DBG(_log_inst, _data, _length, _str) \
701 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_DBG, _log_inst, _data, _length, _str)
702
704
717void z_log_vprintk(const char *fmt, va_list ap);
718
719#ifdef __cplusplus
720}
721#define LOG_IN_CPLUSPLUS 1
722#endif
723/* Macro expects that optionally on second argument local log level is provided.
724 * If provided it is returned, otherwise default log level is returned or
725 * LOG_LEVEL, if it was locally defined.
726 */
727#if !defined(CONFIG_LOG)
728#define _LOG_LEVEL_RESOLVE(...) LOG_LEVEL_NONE
729#else
730#define _LOG_LEVEL_RESOLVE(...) \
731 Z_LOG_EVAL(COND_CODE_0(LOG_LEVEL, (1), (LOG_LEVEL)), \
732 (GET_ARG_N(2, __VA_ARGS__, LOG_LEVEL)), \
733 (GET_ARG_N(2, __VA_ARGS__, CONFIG_LOG_DEFAULT_LEVEL)))
734#endif
735
736/* Return first argument */
737#define _LOG_ARG1(arg1, ...) arg1
738
739#define _LOG_MODULE_CONST_DATA_CREATE(_name, _level) \
740 IF_ENABLED(CONFIG_LOG_FMT_SECTION, ( \
741 static const char UTIL_CAT(_name, _str)[] \
742 __in_section(_log_strings, static, _CONCAT(_name, _)) __used __noasan = \
743 STRINGIFY(_name);)) \
744 IF_ENABLED(LOG_IN_CPLUSPLUS, (extern)) \
745 const STRUCT_SECTION_ITERABLE_ALTERNATE(log_const, log_source_const_data, \
746 Z_LOG_ITEM_CONST_DATA(_name)) = { \
747 .name = COND_CODE_1(CONFIG_LOG_FMT_SECTION, \
748 (UTIL_CAT(_name, _str)), (STRINGIFY(_name))), .level = (_level)}
749
750#define _LOG_MODULE_DYNAMIC_DATA_CREATE(_name) \
751 STRUCT_SECTION_ITERABLE_ALTERNATE(log_dynamic, log_source_dynamic_data, \
752 LOG_ITEM_DYNAMIC_DATA(_name))
753
754#define _LOG_MODULE_DYNAMIC_DATA_COND_CREATE(_name) \
755 IF_ENABLED(CONFIG_LOG_RUNTIME_FILTERING, \
756 (_LOG_MODULE_DYNAMIC_DATA_CREATE(_name);))
757
758#define _LOG_MODULE_DATA_CREATE(_name, _level) \
759 _LOG_MODULE_CONST_DATA_CREATE(_name, _level); \
760 _LOG_MODULE_DYNAMIC_DATA_COND_CREATE(_name)
761
762/* Determine if data for the module shall be created. It is created if logging
763 * is enabled, override level is set or module specific level is set (not off).
764 */
765#define Z_DO_LOG_MODULE_REGISTER(...) \
766 COND_CODE_1(CONFIG_LOG, \
767 (Z_LOG_EVAL(CONFIG_LOG_OVERRIDE_LEVEL, \
768 (1), \
769 (Z_LOG_EVAL(_LOG_LEVEL_RESOLVE(__VA_ARGS__), (1), (0))) \
770 )), (0))
771
772/* Determine if the data of the log module shall be in the partition
773 * 'k_log_partition' to allow a user mode thread access to this data.
774 */
775#if defined(CONFIG_USERSPACE) && defined(CONFIG_LOG_ALWAYS_RUNTIME)
776extern struct k_mem_partition k_log_partition;
777#define Z_LOG_MODULE_PARTITION(_k_app_mem) _k_app_mem(k_log_partition)
778#else
779#define Z_LOG_MODULE_PARTITION(_k_app_mem)
780#endif
781
782/* Declare the data of the log module. The declarations must precede the
783 * definition created by LOG_MODULE_REGISTER(): redeclaring an object after its
784 * definition is reported by -Wtentative-definition-compat (Clang 21).
785 */
786#define Z_LOG_MODULE_DECLARE_EXTERN(...) \
787 extern const struct log_source_const_data Z_LOG_ITEM_CONST_DATA( \
788 GET_ARG_N(1, __VA_ARGS__)); \
789 extern struct log_source_dynamic_data LOG_ITEM_DYNAMIC_DATA(GET_ARG_N(1, __VA_ARGS__))
790
791/* Create the file local pointers to the data of the log module. */
792#define Z_LOG_MODULE_DECLARE_LOCAL(...) \
793 Z_LOG_MODULE_PARTITION(K_APP_DMEM) \
794 static const struct log_source_const_data *__log_current_const_data __unused = \
795 Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__) \
796 ? &Z_LOG_ITEM_CONST_DATA(GET_ARG_N(1, __VA_ARGS__)) \
797 : NULL; \
798 \
799 Z_LOG_MODULE_PARTITION(K_APP_DMEM) \
800 static struct log_source_dynamic_data *__log_current_dynamic_data __unused = \
801 (Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__) && \
802 IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) \
803 ? &LOG_ITEM_DYNAMIC_DATA(GET_ARG_N(1, __VA_ARGS__)) \
804 : NULL; \
805 \
806 Z_LOG_MODULE_PARTITION(K_APP_BMEM) \
807 static const uint32_t __log_level __unused = _LOG_LEVEL_RESOLVE(__VA_ARGS__)
808
813
845#define LOG_MODULE_REGISTER(...) \
846 Z_LOG_MODULE_DECLARE_EXTERN(__VA_ARGS__); \
847 COND_CODE_1( \
848 Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__), \
849 (_LOG_MODULE_DATA_CREATE(GET_ARG_N(1, __VA_ARGS__), \
850 _LOG_LEVEL_RESOLVE(__VA_ARGS__))),\
851 () \
852 ) \
853 Z_LOG_MODULE_DECLARE_LOCAL(__VA_ARGS__)
854
881#define LOG_MODULE_DECLARE(...) \
882 Z_LOG_MODULE_DECLARE_EXTERN(__VA_ARGS__); \
883 Z_LOG_MODULE_DECLARE_LOCAL(__VA_ARGS__)
884
892#define LOG_LEVEL_SET(level) \
893 static const uint32_t __log_level __unused = Z_LOG_RESOLVED_LEVEL(level, 0)
894
896
897#ifdef CONFIG_LOG_CUSTOM_HEADER
898/* This include must always be at the end of log.h */
899#include <zephyr_custom_log.h>
900#endif
901
902/*
903 * Eclipse CDT or JetBrains Clion parser is sometimes confused by logging API
904 * code and freezes the whole IDE. Following lines hides LOG_x macros from them.
905 */
906#if defined(__CDT_PARSER__) || defined(__JETBRAINS_IDE__)
907#undef LOG_ERR
908#undef LOG_WRN
909#undef LOG_INF
910#undef LOG_DBG
911
912#undef LOG_HEXDUMP_ERR
913#undef LOG_HEXDUMP_WRN
914#undef LOG_HEXDUMP_INF
915#undef LOG_HEXDUMP_DBG
916
917#define LOG_ERR(...) (void)0
918#define LOG_WRN(...) (void)0
919#define LOG_DBG(...) (void)0
920#define LOG_INF(...) (void)0
921
922#define LOG_HEXDUMP_ERR(...) (void)0
923#define LOG_HEXDUMP_WRN(...) (void)0
924#define LOG_HEXDUMP_DBG(...) (void)0
925#define LOG_HEXDUMP_INF(...) (void)0
926
927#undef LOG_ERR_RATELIMIT
928#undef LOG_WRN_RATELIMIT
929#undef LOG_INF_RATELIMIT
930#undef LOG_DBG_RATELIMIT
931
932#undef LOG_ERR_RATELIMIT_RATE
933#undef LOG_WRN_RATELIMIT_RATE
934#undef LOG_INF_RATELIMIT_RATE
935#undef LOG_DBG_RATELIMIT_RATE
936
937#undef LOG_HEXDUMP_ERR_RATELIMIT
938#undef LOG_HEXDUMP_WRN_RATELIMIT
939#undef LOG_HEXDUMP_INF_RATELIMIT
940#undef LOG_HEXDUMP_DBG_RATELIMIT
941
942#undef LOG_HEXDUMP_ERR_RATELIMIT_RATE
943#undef LOG_HEXDUMP_WRN_RATELIMIT_RATE
944#undef LOG_HEXDUMP_INF_RATELIMIT_RATE
945#undef LOG_HEXDUMP_DBG_RATELIMIT_RATE
946
947#define LOG_ERR_RATELIMIT(...) (void)0
948#define LOG_WRN_RATELIMIT(...) (void)0
949#define LOG_INF_RATELIMIT(...) (void)0
950#define LOG_DBG_RATELIMIT(...) (void)0
951
952#define LOG_HEXDUMP_ERR_RATELIMIT(...) (void)0
953#define LOG_HEXDUMP_WRN_RATELIMIT(...) (void)0
954#define LOG_HEXDUMP_INF_RATELIMIT(...) (void)0
955#define LOG_HEXDUMP_DBG_RATELIMIT(...) (void)0
956
957#define LOG_ERR_RATELIMIT_RATE(...) (void)0
958#define LOG_WRN_RATELIMIT_RATE(...) (void)0
959#define LOG_INF_RATELIMIT_RATE(...) (void)0
960#define LOG_DBG_RATELIMIT_RATE(...) (void)0
961
962#define LOG_HEXDUMP_ERR_RATELIMIT_RATE(...) (void)0
963#define LOG_HEXDUMP_WRN_RATELIMIT_RATE(...) (void)0
964#define LOG_HEXDUMP_INF_RATELIMIT_RATE(...) (void)0
965#define LOG_HEXDUMP_DBG_RATELIMIT_RATE(...) (void)0
966#endif
967
971
972#endif /* ZEPHYR_INCLUDE_LOGGING_LOG_H_ */
Public kernel APIs.
Header file for the logging core.
Header file for log instance registration.
Memory Partition.
Definition mem_domain.h:55
Header file for the Atomic operations API.
Iterable sections helpers.
Macro utilities.