1 /*
2  * Copyright (c) 2018 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_H_
7 #define ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_H_
8 
9 #include <zephyr/logging/log_msg.h>
10 #include <zephyr/sys/util.h>
11 #include <stdarg.h>
12 #include <zephyr/sys/atomic.h>
13 #include <zephyr/kernel.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @brief Log output API
21  * @defgroup log_output Log output API
22  * @ingroup logger
23  * @{
24  */
25 
26 /**@defgroup LOG_OUTPUT_FLAGS Log output formatting flags.
27  * @{
28  */
29 
30 /** @brief Flag forcing ANSI escape code colors, red (errors), yellow
31  *         (warnings).
32  */
33 #define LOG_OUTPUT_FLAG_COLORS			BIT(0)
34 
35 /** @brief Flag forcing timestamp */
36 #define LOG_OUTPUT_FLAG_TIMESTAMP		BIT(1)
37 
38 /** @brief Flag forcing timestamp formatting. */
39 #define LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP	BIT(2)
40 
41 /** @brief Flag forcing severity level prefix. */
42 #define LOG_OUTPUT_FLAG_LEVEL			BIT(3)
43 
44 /** @brief Flag preventing the logger from adding CR and LF characters. */
45 #define LOG_OUTPUT_FLAG_CRLF_NONE		BIT(4)
46 
47 /** @brief Flag forcing a single LF character for line breaks. */
48 #define LOG_OUTPUT_FLAG_CRLF_LFONLY		BIT(5)
49 
50 /** @brief Flag forcing syslog format specified in RFC 5424
51  */
52 #define LOG_OUTPUT_FLAG_FORMAT_SYSLOG		BIT(6)
53 
54 /** @brief Flag thread id or name prefix. */
55 #define LOG_OUTPUT_FLAG_THREAD			BIT(7)
56 
57 /** @brief Flag forcing to skip logging the source. */
58 #define LOG_OUTPUT_FLAG_SKIP_SOURCE		BIT(8)
59 
60 /**@} */
61 
62 /** @brief Supported backend logging format types for use
63  * with log_format_set() API to switch log format at runtime.
64  */
65 #define LOG_OUTPUT_TEXT 0
66 
67 #define LOG_OUTPUT_SYST 1
68 
69 #define LOG_OUTPUT_DICT 2
70 
71 #define LOG_OUTPUT_CUSTOM 3
72 
73 /**
74  * @brief Prototype of the function processing output data.
75  *
76  * @param buf The buffer data.
77  * @param size The buffer size.
78  * @param ctx User context.
79  *
80  * @return Number of bytes processed, dropped or discarded.
81  *
82  * @note If the log output function cannot process all of the data, it is
83  *       its responsibility to mark them as dropped or discarded by returning
84  *       the corresponding number of bytes dropped or discarded to the caller.
85  */
86 typedef int (*log_output_func_t)(uint8_t *buf, size_t size, void *ctx);
87 
88 /* @brief Control block structure for log_output instance.  */
89 struct log_output_control_block {
90 	atomic_t offset;
91 	void *ctx;
92 	const char *hostname;
93 };
94 
95 /** @brief Log_output instance structure. */
96 struct log_output {
97 	log_output_func_t func;
98 	struct log_output_control_block *control_block;
99 	uint8_t *buf;
100 	size_t size;
101 };
102 
103 /**
104  * @brief Typedef of the function pointer table "format_table".
105  *
106  * @param output Pointer to log_output struct.
107  * @param msg Pointer to log_msg struct.
108  * @param flags Flags used for text formatting options.
109  *
110  * @return Function pointer based on Kconfigs defined for backends.
111  */
112 typedef void (*log_format_func_t)(const struct log_output *output,
113 					struct log_msg *msg, uint32_t flags);
114 
115 /**
116  * @brief Declaration of the get routine for function pointer table format_table.
117  */
118 log_format_func_t log_format_func_t_get(uint32_t log_type);
119 
120 /** @brief Create log_output instance.
121  *
122  * @param _name Instance name.
123  * @param _func Function for processing output data.
124  * @param _buf  Pointer to the output buffer.
125  * @param _size Size of the output buffer.
126  */
127 #define LOG_OUTPUT_DEFINE(_name, _func, _buf, _size)			\
128 	static struct log_output_control_block _name##_control_block;	\
129 	static const struct log_output _name = {			\
130 		.func = _func,						\
131 		.control_block = &_name##_control_block,		\
132 		.buf = _buf,						\
133 		.size = _size,						\
134 	}
135 
136 /** @brief Process log messages v2 to readable strings.
137  *
138  * Function is using provided context with the buffer and output function to
139  * process formatted string and output the data.
140  *
141  * @param log_output Pointer to the log output instance.
142  * @param msg Log message.
143  * @param flags Optional flags. See @ref LOG_OUTPUT_FLAGS.
144  */
145 void log_output_msg_process(const struct log_output *log_output,
146 			    struct log_msg *msg, uint32_t flags);
147 
148 /** @brief Process input data to a readable string.
149  *
150  * @param log_output	Pointer to the log output instance.
151  * @param timestamp	Timestamp.
152  * @param domain	Domain name string. Can be NULL.
153  * @param source	Source name string. Can be NULL.
154  * @param tid		Thread ID.
155  * @param level		Criticality level.
156  * @param package	Cbprintf package with a logging message string.
157  * @param data		Data passed to hexdump API. Can be NULL.
158  * @param data_len	Data length.
159  * @param flags		Formatting flags. See @ref LOG_OUTPUT_FLAGS.
160  */
161 void log_output_process(const struct log_output *log_output,
162 			log_timestamp_t timestamp,
163 			const char *domain,
164 			const char *source,
165 			k_tid_t tid,
166 			uint8_t level,
167 			const uint8_t *package,
168 			const uint8_t *data,
169 			size_t data_len,
170 			uint32_t flags);
171 
172 /** @brief Process log messages v2 to SYS-T format.
173  *
174  * Function is using provided context with the buffer and output function to
175  * process formatted string and output the data in sys-t log output format.
176  *
177  * @param log_output Pointer to the log output instance.
178  * @param msg Log message.
179  * @param flags Optional flags. See @ref LOG_OUTPUT_FLAGS.
180  */
181 void log_output_msg_syst_process(const struct log_output *log_output,
182 				  struct log_msg *msg, uint32_t flags);
183 
184 /** @brief Process dropped messages indication.
185  *
186  * Function prints error message indicating lost log messages.
187  *
188  * @param output Pointer to the log output instance.
189  * @param cnt        Number of dropped messages.
190  */
191 void log_output_dropped_process(const struct log_output *output, uint32_t cnt);
192 
193 /** @brief Write to the output buffer.
194  *
195  * @param outf Output function.
196  * @param buf  Buffer.
197  * @param len  Buffer length.
198  * @param ctx  Context passed to the %p outf.
199  */
log_output_write(log_output_func_t outf,uint8_t * buf,size_t len,void * ctx)200 static inline void log_output_write(log_output_func_t outf, uint8_t *buf, size_t len, void *ctx)
201 {
202 	int processed;
203 
204 	while (len != 0) {
205 		processed = outf(buf, len, ctx);
206 		len -= processed;
207 		buf += processed;
208 	}
209 }
210 
211 /** @brief Flush output buffer.
212  *
213  * @param output Pointer to the log output instance.
214  */
log_output_flush(const struct log_output * output)215 static inline void log_output_flush(const struct log_output *output)
216 {
217 	log_output_write(output->func, output->buf, output->control_block->offset,
218 			 output->control_block->ctx);
219 	output->control_block->offset = 0;
220 }
221 
222 /** @brief Function for setting user context passed to the output function.
223  *
224  * @param output	Pointer to the log output instance.
225  * @param ctx		User context.
226  */
log_output_ctx_set(const struct log_output * output,void * ctx)227 static inline void log_output_ctx_set(const struct log_output *output,
228 				      void *ctx)
229 {
230 	output->control_block->ctx = ctx;
231 }
232 
233 /** @brief Function for setting hostname of this device
234  *
235  * @param output	Pointer to the log output instance.
236  * @param hostname	Hostname of this device
237  */
log_output_hostname_set(const struct log_output * output,const char * hostname)238 static inline void log_output_hostname_set(const struct log_output *output,
239 					   const char *hostname)
240 {
241 	output->control_block->hostname = hostname;
242 }
243 
244 /** @brief Set timestamp frequency.
245  *
246  * @param freq Frequency in Hz.
247  */
248 void log_output_timestamp_freq_set(uint32_t freq);
249 
250 /** @brief Convert timestamp of the message to us.
251  *
252  * @param timestamp Message timestamp
253  *
254  * @return Timestamp value in us.
255  */
256 uint64_t log_output_timestamp_to_us(log_timestamp_t timestamp);
257 
258 /**
259  * @}
260  */
261 
262 
263 #ifdef __cplusplus
264 }
265 #endif
266 
267 #endif /* ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_H_ */
268