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 static atomic_t __last_log_time; \
158 static atomic_t __skipped_count; \
159 uint32_t __now = k_uptime_get_32(); \
160 uint32_t __last = atomic_get(&__last_log_time); \
161 uint32_t __diff = __now - __last; \
162 if (unlikely(__diff >= (_rate_ms))) { \
163 if (atomic_cas(&__last_log_time, __last, __now)) { \
164 uint32_t __skipped = atomic_clear(&__skipped_count); \
165 if (__skipped > 0) { \
166 Z_LOG(_level, "Skipped %d messages", __skipped); \
167 } \
168 Z_LOG(_level, __VA_ARGS__); \
169 } else { \
170 atomic_inc(&__skipped_count); \
171 } \
172 } else { \
173 atomic_inc(&__skipped_count); \
174 } \
175 } while (0)
176
188#define _LOG_RATELIMIT_LVL(_level, _rate_ms, ...) \
189 do { \
190 if (IS_ENABLED(CONFIG_LOG_RATELIMIT)) { \
191 _LOG_RATELIMIT_CORE(_level, _rate_ms, __VA_ARGS__); \
192 } else if (IS_ENABLED(CONFIG_LOG_RATELIMIT_FALLBACK_DROP)) { \
193 (void)0; \
194 } else { \
195 Z_LOG(_level, __VA_ARGS__); \
196 } \
197 } while (0)
198
209#define LOG_WRN_RATELIMIT(...) \
210 _LOG_RATELIMIT_LVL(LOG_LEVEL_WRN, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
211
223#define LOG_ERR_RATELIMIT(...) \
224 _LOG_RATELIMIT_LVL(LOG_LEVEL_ERR, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
225
236#define LOG_INF_RATELIMIT(...) \
237 _LOG_RATELIMIT_LVL(LOG_LEVEL_INF, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
238
249#define LOG_DBG_RATELIMIT(...) \
250 _LOG_RATELIMIT_LVL(LOG_LEVEL_DBG, LOG_RATELIMIT_INTERVAL_MS, __VA_ARGS__)
251
266#define _LOG_HEXDUMP_RATELIMIT_CORE(_level, _rate_ms, _data, _length, _str) \
267 do { \
268 static atomic_t __last_log_time; \
269 static atomic_t __skipped_count; \
270 uint32_t __now = k_uptime_get_32(); \
271 uint32_t __last = atomic_get(&__last_log_time); \
272 uint32_t __diff = __now - __last; \
273 if (unlikely(__diff >= (_rate_ms))) { \
274 if (atomic_cas(&__last_log_time, __last, __now)) { \
275 uint32_t __skipped = atomic_clear(&__skipped_count); \
276 if (__skipped > 0) { \
277 Z_LOG(_level, "Skipped %d hexdump messages", __skipped); \
278 } \
279 Z_LOG_HEXDUMP(_level, _data, _length, _str); \
280 } else { \
281 atomic_inc(&__skipped_count); \
282 } \
283 } else { \
284 atomic_inc(&__skipped_count); \
285 } \
286 } while (0)
287
301#define _LOG_HEXDUMP_RATELIMIT_LVL(_level, _rate_ms, _data, _length, _str) \
302 do { \
303 if (IS_ENABLED(CONFIG_LOG_RATELIMIT)) { \
304 _LOG_HEXDUMP_RATELIMIT_CORE(_level, _rate_ms, _data, _length, _str); \
305 } else if (IS_ENABLED(CONFIG_LOG_RATELIMIT_FALLBACK_DROP)) { \
306 (void)0; \
307 } else { \
308 Z_LOG_HEXDUMP(_level, _data, _length, _str); \
309 } \
310 } while (0)
311
324#define LOG_HEXDUMP_ERR_RATELIMIT(_data, _length, _str) \
325 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_ERR, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
326
339#define LOG_HEXDUMP_WRN_RATELIMIT(_data, _length, _str) \
340 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_WRN, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
341
353#define LOG_HEXDUMP_INF_RATELIMIT(_data, _length, _str) \
354 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_INF, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
355
367#define LOG_HEXDUMP_DBG_RATELIMIT(_data, _length, _str) \
368 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_DBG, LOG_RATELIMIT_INTERVAL_MS, _data, _length, _str)
369
381#define LOG_ERR_RATELIMIT_RATE(_rate_ms, ...) \
382 _LOG_RATELIMIT_LVL(LOG_LEVEL_ERR, _rate_ms, __VA_ARGS__)
383
395#define LOG_WRN_RATELIMIT_RATE(_rate_ms, ...) \
396 _LOG_RATELIMIT_LVL(LOG_LEVEL_WRN, _rate_ms, __VA_ARGS__)
397
409#define LOG_INF_RATELIMIT_RATE(_rate_ms, ...) \
410 _LOG_RATELIMIT_LVL(LOG_LEVEL_INF, _rate_ms, __VA_ARGS__)
411
423#define LOG_DBG_RATELIMIT_RATE(_rate_ms, ...) \
424 _LOG_RATELIMIT_LVL(LOG_LEVEL_DBG, _rate_ms, __VA_ARGS__)
425
438#define LOG_HEXDUMP_ERR_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
439 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_ERR, _rate_ms, _data, _length, _str)
440
453#define LOG_HEXDUMP_WRN_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
454 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_WRN, _rate_ms, _data, _length, _str)
455
468#define LOG_HEXDUMP_INF_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
469 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_INF, _rate_ms, _data, _length, _str)
470
483#define LOG_HEXDUMP_DBG_RATELIMIT_RATE(_rate_ms, _data, _length, _str) \
484 _LOG_HEXDUMP_RATELIMIT_LVL(LOG_LEVEL_DBG, _rate_ms, _data, _length, _str)
485
487
492
502#define LOG_PRINTK(...) Z_LOG_PRINTK(0, __VA_ARGS__)
503
512#define LOG_RAW(...) Z_LOG_PRINTK(1, __VA_ARGS__)
513
515
520
533#define LOG_INST_ERR(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_ERR, _log_inst, __VA_ARGS__)
534
548#define LOG_INST_WRN(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_WRN, _log_inst, __VA_ARGS__)
549
562#define LOG_INST_INF(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_INF, _log_inst, __VA_ARGS__)
563
576#define LOG_INST_DBG(_log_inst, ...) Z_LOG_INSTANCE(LOG_LEVEL_DBG, _log_inst, __VA_ARGS__)
577
579
584
595#define LOG_HEXDUMP_ERR(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_ERR, _data, _length, (_str))
596
607#define LOG_HEXDUMP_WRN(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_WRN, _data, _length, (_str))
608
618#define LOG_HEXDUMP_INF(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_INF, _data, _length, (_str))
619
629#define LOG_HEXDUMP_DBG(_data, _length, _str) Z_LOG_HEXDUMP(LOG_LEVEL_DBG, _data, _length, (_str))
630
632
637
652#define LOG_INST_HEXDUMP_ERR(_log_inst, _data, _length, _str) \
653 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_ERR, _log_inst, _data, _length, _str)
654
667#define LOG_INST_HEXDUMP_WRN(_log_inst, _data, _length, _str) \
668 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_WRN, _log_inst, _data, _length, _str)
669
681#define LOG_INST_HEXDUMP_INF(_log_inst, _data, _length, _str) \
682 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_INF, _log_inst, _data, _length, _str)
683
695#define LOG_INST_HEXDUMP_DBG(_log_inst, _data, _length, _str) \
696 Z_LOG_HEXDUMP_INSTANCE(LOG_LEVEL_DBG, _log_inst, _data, _length, _str)
697
699
712void z_log_vprintk(const char *fmt, va_list ap);
713
714#ifdef __cplusplus
715}
716#define LOG_IN_CPLUSPLUS 1
717#endif
718/* Macro expects that optionally on second argument local log level is provided.
719 * If provided it is returned, otherwise default log level is returned or
720 * LOG_LEVEL, if it was locally defined.
721 */
722#if !defined(CONFIG_LOG)
723#define _LOG_LEVEL_RESOLVE(...) LOG_LEVEL_NONE
724#else
725#define _LOG_LEVEL_RESOLVE(...) \
726 Z_LOG_EVAL(COND_CODE_0(LOG_LEVEL, (1), (LOG_LEVEL)), \
727 (GET_ARG_N(2, __VA_ARGS__, LOG_LEVEL)), \
728 (GET_ARG_N(2, __VA_ARGS__, CONFIG_LOG_DEFAULT_LEVEL)))
729#endif
730
731/* Return first argument */
732#define _LOG_ARG1(arg1, ...) arg1
733
734#define _LOG_MODULE_CONST_DATA_CREATE(_name, _level) \
735 IF_ENABLED(CONFIG_LOG_FMT_SECTION, ( \
736 static const char UTIL_CAT(_name, _str)[] \
737 __in_section(_log_strings, static, _CONCAT(_name, _)) __used __noasan = \
738 STRINGIFY(_name);)) \
739 IF_ENABLED(LOG_IN_CPLUSPLUS, (extern)) \
740 const STRUCT_SECTION_ITERABLE_ALTERNATE(log_const, log_source_const_data, \
741 Z_LOG_ITEM_CONST_DATA(_name)) = { \
742 .name = COND_CODE_1(CONFIG_LOG_FMT_SECTION, \
743 (UTIL_CAT(_name, _str)), (STRINGIFY(_name))), .level = (_level)}
744
745#define _LOG_MODULE_DYNAMIC_DATA_CREATE(_name) \
746 STRUCT_SECTION_ITERABLE_ALTERNATE(log_dynamic, log_source_dynamic_data, \
747 LOG_ITEM_DYNAMIC_DATA(_name))
748
749#define _LOG_MODULE_DYNAMIC_DATA_COND_CREATE(_name) \
750 IF_ENABLED(CONFIG_LOG_RUNTIME_FILTERING, \
751 (_LOG_MODULE_DYNAMIC_DATA_CREATE(_name);))
752
753#define _LOG_MODULE_DATA_CREATE(_name, _level) \
754 _LOG_MODULE_CONST_DATA_CREATE(_name, _level); \
755 _LOG_MODULE_DYNAMIC_DATA_COND_CREATE(_name)
756
757/* Determine if data for the module shall be created. It is created if logging
758 * is enabled, override level is set or module specific level is set (not off).
759 */
760#define Z_DO_LOG_MODULE_REGISTER(...) \
761 COND_CODE_1(CONFIG_LOG, \
762 (Z_LOG_EVAL(CONFIG_LOG_OVERRIDE_LEVEL, \
763 (1), \
764 (Z_LOG_EVAL(_LOG_LEVEL_RESOLVE(__VA_ARGS__), (1), (0))) \
765 )), (0))
766
767/* Determine if the data of the log module shall be in the partition
768 * 'k_log_partition' to allow a user mode thread access to this data.
769 */
770#if defined(CONFIG_USERSPACE) && defined(CONFIG_LOG_ALWAYS_RUNTIME)
771extern struct k_mem_partition k_log_partition;
772#define Z_LOG_MODULE_PARTITION(_k_app_mem) _k_app_mem(k_log_partition)
773#else
774#define Z_LOG_MODULE_PARTITION(_k_app_mem)
775#endif
776
781
813#define LOG_MODULE_REGISTER(...) \
814 COND_CODE_1( \
815 Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__), \
816 (_LOG_MODULE_DATA_CREATE(GET_ARG_N(1, __VA_ARGS__), \
817 _LOG_LEVEL_RESOLVE(__VA_ARGS__))),\
818 () \
819 ) \
820 LOG_MODULE_DECLARE(__VA_ARGS__)
821
848#define LOG_MODULE_DECLARE(...) \
849 extern const struct log_source_const_data Z_LOG_ITEM_CONST_DATA( \
850 GET_ARG_N(1, __VA_ARGS__)); \
851 extern struct log_source_dynamic_data LOG_ITEM_DYNAMIC_DATA(GET_ARG_N(1, __VA_ARGS__)); \
852 \
853 Z_LOG_MODULE_PARTITION(K_APP_DMEM) \
854 static const struct log_source_const_data *__log_current_const_data __unused = \
855 Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__) \
856 ? &Z_LOG_ITEM_CONST_DATA(GET_ARG_N(1, __VA_ARGS__)) \
857 : NULL; \
858 \
859 Z_LOG_MODULE_PARTITION(K_APP_DMEM) \
860 static struct log_source_dynamic_data *__log_current_dynamic_data __unused = \
861 (Z_DO_LOG_MODULE_REGISTER(__VA_ARGS__) && \
862 IS_ENABLED(CONFIG_LOG_RUNTIME_FILTERING)) \
863 ? &LOG_ITEM_DYNAMIC_DATA(GET_ARG_N(1, __VA_ARGS__)) \
864 : NULL; \
865 \
866 Z_LOG_MODULE_PARTITION(K_APP_BMEM) \
867 static const uint32_t __log_level __unused = _LOG_LEVEL_RESOLVE(__VA_ARGS__)
868
876#define LOG_LEVEL_SET(level) \
877 static const uint32_t __log_level __unused = Z_LOG_RESOLVED_LEVEL(level, 0)
878
880
881#ifdef CONFIG_LOG_CUSTOM_HEADER
882/* This include must always be at the end of log.h */
883#include <zephyr_custom_log.h>
884#endif
885
886/*
887 * Eclipse CDT or JetBrains Clion parser is sometimes confused by logging API
888 * code and freezes the whole IDE. Following lines hides LOG_x macros from them.
889 */
890#if defined(__CDT_PARSER__) || defined(__JETBRAINS_IDE__)
891#undef LOG_ERR
892#undef LOG_WRN
893#undef LOG_INF
894#undef LOG_DBG
895
896#undef LOG_HEXDUMP_ERR
897#undef LOG_HEXDUMP_WRN
898#undef LOG_HEXDUMP_INF
899#undef LOG_HEXDUMP_DBG
900
901#define LOG_ERR(...) (void)0
902#define LOG_WRN(...) (void)0
903#define LOG_DBG(...) (void)0
904#define LOG_INF(...) (void)0
905
906#define LOG_HEXDUMP_ERR(...) (void)0
907#define LOG_HEXDUMP_WRN(...) (void)0
908#define LOG_HEXDUMP_DBG(...) (void)0
909#define LOG_HEXDUMP_INF(...) (void)0
910
911#undef LOG_ERR_RATELIMIT
912#undef LOG_WRN_RATELIMIT
913#undef LOG_INF_RATELIMIT
914#undef LOG_DBG_RATELIMIT
915
916#undef LOG_ERR_RATELIMIT_RATE
917#undef LOG_WRN_RATELIMIT_RATE
918#undef LOG_INF_RATELIMIT_RATE
919#undef LOG_DBG_RATELIMIT_RATE
920
921#undef LOG_HEXDUMP_ERR_RATELIMIT
922#undef LOG_HEXDUMP_WRN_RATELIMIT
923#undef LOG_HEXDUMP_INF_RATELIMIT
924#undef LOG_HEXDUMP_DBG_RATELIMIT
925
926#undef LOG_HEXDUMP_ERR_RATELIMIT_RATE
927#undef LOG_HEXDUMP_WRN_RATELIMIT_RATE
928#undef LOG_HEXDUMP_INF_RATELIMIT_RATE
929#undef LOG_HEXDUMP_DBG_RATELIMIT_RATE
930
931#define LOG_ERR_RATELIMIT(...) (void)0
932#define LOG_WRN_RATELIMIT(...) (void)0
933#define LOG_INF_RATELIMIT(...) (void)0
934#define LOG_DBG_RATELIMIT(...) (void)0
935
936#define LOG_HEXDUMP_ERR_RATELIMIT(...) (void)0
937#define LOG_HEXDUMP_WRN_RATELIMIT(...) (void)0
938#define LOG_HEXDUMP_INF_RATELIMIT(...) (void)0
939#define LOG_HEXDUMP_DBG_RATELIMIT(...) (void)0
940
941#define LOG_ERR_RATELIMIT_RATE(...) (void)0
942#define LOG_WRN_RATELIMIT_RATE(...) (void)0
943#define LOG_INF_RATELIMIT_RATE(...) (void)0
944#define LOG_DBG_RATELIMIT_RATE(...) (void)0
945
946#define LOG_HEXDUMP_ERR_RATELIMIT_RATE(...) (void)0
947#define LOG_HEXDUMP_WRN_RATELIMIT_RATE(...) (void)0
948#define LOG_HEXDUMP_INF_RATELIMIT_RATE(...) (void)0
949#define LOG_HEXDUMP_DBG_RATELIMIT_RATE(...) (void)0
950#endif
951
955
956#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.