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 <logging/log_msg.h>
10 #include <sys/util.h>
11 #include <stdarg.h>
12 #include <sys/atomic.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 /**
19  * @brief Log output API
20  * @defgroup log_output Log output API
21  * @ingroup logger
22  * @{
23  */
24 
25 /** @brief Flag forcing ANSI escape code colors, red (errors), yellow
26  *         (warnings).
27  */
28 #define LOG_OUTPUT_FLAG_COLORS			BIT(0)
29 
30 /** @brief Flag forcing timestamp */
31 #define LOG_OUTPUT_FLAG_TIMESTAMP		BIT(1)
32 
33 /** @brief Flag forcing timestamp formatting. */
34 #define LOG_OUTPUT_FLAG_FORMAT_TIMESTAMP	BIT(2)
35 
36 /** @brief Flag forcing severity level prefix. */
37 #define LOG_OUTPUT_FLAG_LEVEL			BIT(3)
38 
39 /** @brief Flag preventing the logger from adding CR and LF characters. */
40 #define LOG_OUTPUT_FLAG_CRLF_NONE		BIT(4)
41 
42 /** @brief Flag forcing a single LF character for line breaks. */
43 #define LOG_OUTPUT_FLAG_CRLF_LFONLY		BIT(5)
44 
45 /** @brief Flag forcing syslog format specified in RFC 5424
46  */
47 #define LOG_OUTPUT_FLAG_FORMAT_SYSLOG		BIT(6)
48 
49 /** @brief Flag forcing syslog format specified in mipi sys-t
50  */
51 #define LOG_OUTPUT_FLAG_FORMAT_SYST		BIT(7)
52 
53 /**
54  * @brief Prototype of the function processing output data.
55  *
56  * @param buf The buffer data.
57  * @param size The buffer size.
58  * @param ctx User context.
59  *
60  * @return Number of bytes processed, dropped or discarded.
61  *
62  * @note If the log output function cannot process all of the data, it is
63  *       its responsibility to mark them as dropped or discarded by returning
64  *       the corresponding number of bytes dropped or discarded to the caller.
65  */
66 typedef int (*log_output_func_t)(uint8_t *buf, size_t size, void *ctx);
67 
68 /* @brief Control block structure for log_output instance.  */
69 struct log_output_control_block {
70 	atomic_t offset;
71 	void *ctx;
72 	const char *hostname;
73 };
74 
75 /** @brief Log_output instance structure. */
76 struct log_output {
77 	log_output_func_t func;
78 	struct log_output_control_block *control_block;
79 	uint8_t *buf;
80 	size_t size;
81 };
82 
83 /** @brief Create log_output instance.
84  *
85  * @param _name Instance name.
86  * @param _func Function for processing output data.
87  * @param _buf  Pointer to the output buffer.
88  * @param _size Size of the output buffer.
89  */
90 #define LOG_OUTPUT_DEFINE(_name, _func, _buf, _size)			\
91 	static struct log_output_control_block _name##_control_block;	\
92 	static const struct log_output _name = {			\
93 		.func = _func,						\
94 		.control_block = &_name##_control_block,		\
95 		.buf = _buf,						\
96 		.size = _size,						\
97 	}
98 
99 /** @brief Process log messages to readable strings.
100  *
101  * Function is using provided context with the buffer and output function to
102  * process formatted string and output the data.
103  *
104  * @param output Pointer to the log output instance.
105  * @param msg Log message.
106  * @param flags Optional flags.
107  */
108 void log_output_msg_process(const struct log_output *output,
109 			    struct log_msg *msg,
110 			    uint32_t flags);
111 
112 /** @brief Process log messages v2 to readable strings.
113  *
114  * Function is using provided context with the buffer and output function to
115  * process formatted string and output the data.
116  *
117  * @param log_output Pointer to the log output instance.
118  * @param msg Log message.
119  * @param flags Optional flags.
120  */
121 void log_output_msg2_process(const struct log_output *log_output,
122 			     struct log_msg2 *msg, uint32_t flags);
123 
124 /** @brief Process log string
125  *
126  * Function is formatting provided string adding optional prefixes and
127  * postfixes.
128  *
129  * @param output Pointer to log_output instance.
130  * @param src_level  Log source and level structure.
131  * @param timestamp  Timestamp.
132  * @param fmt        String.
133  * @param ap         String arguments.
134  * @param flags      Optional flags.
135  *
136  */
137 void log_output_string(const struct log_output *output,
138 		       struct log_msg_ids src_level, uint32_t timestamp,
139 		       const char *fmt, va_list ap, uint32_t flags);
140 
141 /** @brief Process log hexdump
142  *
143  * Function is formatting provided hexdump adding optional prefixes and
144  * postfixes.
145  *
146  * @param output Pointer to log_output instance.
147  * @param src_level  Log source and level structure.
148  * @param timestamp  Timestamp.
149  * @param metadata   String.
150  * @param data       Data.
151  * @param length     Data length.
152  * @param flags      Optional flags.
153  *
154  */
155 void log_output_hexdump(const struct log_output *output,
156 			     struct log_msg_ids src_level, uint32_t timestamp,
157 			     const char *metadata, const uint8_t *data,
158 			     uint32_t length, uint32_t flags);
159 
160 /** @brief Process dropped messages indication.
161  *
162  * Function prints error message indicating lost log messages.
163  *
164  * @param output Pointer to the log output instance.
165  * @param cnt        Number of dropped messages.
166  */
167 void log_output_dropped_process(const struct log_output *output, uint32_t cnt);
168 
169 /** @brief Flush output buffer.
170  *
171  * @param output Pointer to the log output instance.
172  */
173 void log_output_flush(const struct log_output *output);
174 
175 /** @brief Function for setting user context passed to the output function.
176  *
177  * @param output	Pointer to the log output instance.
178  * @param ctx		User context.
179  */
log_output_ctx_set(const struct log_output * output,void * ctx)180 static inline void log_output_ctx_set(const struct log_output *output,
181 				      void *ctx)
182 {
183 	output->control_block->ctx = ctx;
184 }
185 
186 /** @brief Function for setting hostname of this device
187  *
188  * @param output	Pointer to the log output instance.
189  * @param hostname	Hostname of this device
190  */
log_output_hostname_set(const struct log_output * output,const char * hostname)191 static inline void log_output_hostname_set(const struct log_output *output,
192 					   const char *hostname)
193 {
194 	output->control_block->hostname = hostname;
195 }
196 
197 /** @brief Set timestamp frequency.
198  *
199  * @param freq Frequency in Hz.
200  */
201 void log_output_timestamp_freq_set(uint32_t freq);
202 
203 /** @brief Convert timestamp of the message to us.
204  *
205  * @param timestamp Message timestamp
206  *
207  * @return Timestamp value in us.
208  */
209 uint64_t log_output_timestamp_to_us(uint32_t timestamp);
210 
211 /**
212  * @}
213  */
214 
215 
216 #ifdef __cplusplus
217 }
218 #endif
219 
220 #endif /* ZEPHYR_INCLUDE_LOGGING_LOG_OUTPUT_H_ */
221