1 | /* |
2 | * libwebsockets - small server side websockets and web server implementation |
3 | * |
4 | * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com> |
5 | * |
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | * of this software and associated documentation files (the "Software"), to |
8 | * deal in the Software without restriction, including without limitation the |
9 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
10 | * sell copies of the Software, and to permit persons to whom the Software is |
11 | * furnished to do so, subject to the following conditions: |
12 | * |
13 | * The above copyright notice and this permission notice shall be included in |
14 | * all copies or substantial portions of the Software. |
15 | * |
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
22 | * IN THE SOFTWARE. |
23 | */ |
24 | |
25 | /** \defgroup log Logging |
26 | * |
27 | * ##Logging |
28 | * |
29 | * Lws provides flexible and filterable logging facilities, which can be |
30 | * used inside lws and in user code. |
31 | * |
32 | * Log categories may be individually filtered bitwise, and directed to built-in |
33 | * sinks for syslog-compatible logging, or a user-defined function. |
34 | * |
35 | * Traditional logs use a single, processwide logging context. New style log |
36 | * apis (lws_xxx_cx()) can pass the logging context to use in. |
37 | */ |
38 | ///@{ |
39 | |
40 | #define LLL_ERR (1 << 0) |
41 | #define LLL_WARN (1 << 1) |
42 | #define LLL_NOTICE (1 << 2) |
43 | #define LLL_INFO (1 << 3) |
44 | #define LLL_DEBUG (1 << 4) |
45 | #define LLL_PARSER (1 << 5) |
46 | #define (1 << 6) |
47 | #define LLL_EXT (1 << 7) |
48 | #define LLL_CLIENT (1 << 8) |
49 | #define LLL_LATENCY (1 << 9) |
50 | #define LLL_USER (1 << 10) |
51 | #define LLL_THREAD (1 << 11) |
52 | |
53 | #define LLL_COUNT (12) /* set to count of valid flags */ |
54 | |
55 | #define LLLF_SECRECY_PII (1 << 16) |
56 | /**< contains Personally Identifiable Information */ |
57 | #define LLLF_SECRECY_BEARER (1 << 17) |
58 | /**< possession of this data allows impersonation */ |
59 | |
60 | #define LLLF_LOG_TIMESTAMP (1 << 18) |
61 | /**< set to prepend logs with timestamp */ |
62 | |
63 | #define LLLF_LOG_CONTEXT_AWARE (1 << 30) |
64 | /**< set if the context uses an emit function that takes the logctx, auto- |
65 | * applied when setting emit using lws_set_log_level_cx() api */ |
66 | |
67 | struct lws_log_cx; |
68 | |
69 | typedef void (*lws_log_emit_t)(int level, const char *line); |
70 | typedef void (*lws_log_emit_cx_t)(struct lws_log_cx *cx, int level, |
71 | const char *line, size_t len); |
72 | typedef void (*lws_log_prepend_cx_t)(struct lws_log_cx *cx, void *obj, |
73 | char **p, char *e); |
74 | typedef void (*lws_log_use_cx_t)(struct lws_log_cx *cx, int _new); |
75 | |
76 | /* |
77 | * This is the logging context |
78 | */ |
79 | |
80 | typedef struct lws_log_cx { |
81 | union { |
82 | lws_log_emit_t emit; /* legacy emit function */ |
83 | lws_log_emit_cx_t emit_cx; /* LLLF_LOG_CONTEXT_AWARE */ |
84 | } u; |
85 | |
86 | #if LWS_MAX_SMP > 1 |
87 | pthread_mutex_t refcount_lock; |
88 | #endif |
89 | |
90 | lws_log_use_cx_t refcount_cb; |
91 | /**< NULL, or a function called after each change to .refcount below, |
92 | * this enables implementing side-effects like opening and closing |
93 | * log files when the first and last object binds / unbinds */ |
94 | lws_log_prepend_cx_t prepend; |
95 | /**< NULL, or a cb to optionally prepend a string to logs we are a |
96 | * parent of */ |
97 | struct lws_log_cx *parent; |
98 | /**< NULL, or points to log ctx we are a child of */ |
99 | void *opaque; |
100 | /**< ignored by lws, used to pass config to emit_cx, eg, filepath */ |
101 | void *stg; |
102 | /**< ignored by lws, may be used a storage by refcount_cb / emit_cx */ |
103 | uint32_t lll_flags; |
104 | /**< mask of log levels we want to emit in this context */ |
105 | int32_t refcount; |
106 | /**< refcount of objects bound to this log context */ |
107 | #if LWS_MAX_SMP > 1 |
108 | char inited; |
109 | #endif |
110 | } lws_log_cx_t; |
111 | |
112 | /** |
113 | * lwsl_timestamp: generate logging timestamp string |
114 | * |
115 | * \param level: logging level |
116 | * \param p: char * buffer to take timestamp |
117 | * \param len: length of p |
118 | * |
119 | * returns length written in p |
120 | */ |
121 | LWS_VISIBLE LWS_EXTERN int |
122 | lwsl_timestamp(int level, char *p, size_t len); |
123 | |
124 | #if defined(LWS_PLAT_OPTEE) && !defined(LWS_WITH_NETWORK) |
125 | #define _lws_log(aaa, ...) SMSG(__VA_ARGS__) |
126 | #else |
127 | LWS_VISIBLE LWS_EXTERN void |
128 | _lws_log(int filter, const char *format, ...) LWS_FORMAT(2); |
129 | LWS_VISIBLE LWS_EXTERN void |
130 | _lws_logv(int filter, const char *format, va_list vl); |
131 | #endif |
132 | |
133 | struct lws_vhost; |
134 | struct lws; |
135 | |
136 | LWS_VISIBLE LWS_EXTERN struct lws_log_cx * |
137 | lwsl_context_get_cx(struct lws_context *cx); |
138 | LWS_VISIBLE LWS_EXTERN struct lws_log_cx * |
139 | lwsl_vhost_get_cx(struct lws_vhost *vh); |
140 | LWS_VISIBLE LWS_EXTERN struct lws_log_cx * |
141 | lwsl_wsi_get_cx(struct lws *wsi); |
142 | #if defined(LWS_WITH_SECURE_STREAMS) |
143 | struct lws_ss_handle; |
144 | struct lws_sspc_handle; |
145 | LWS_VISIBLE LWS_EXTERN struct lws_log_cx * |
146 | lwsl_ss_get_cx(struct lws_ss_handle *ss); |
147 | LWS_VISIBLE LWS_EXTERN struct lws_log_cx * |
148 | lwsl_sspc_get_cx(struct lws_sspc_handle *ss); |
149 | #endif |
150 | |
151 | LWS_VISIBLE LWS_EXTERN void |
152 | lws_log_emit_cx_file(struct lws_log_cx *cx, int level, const char *line, |
153 | size_t len); |
154 | |
155 | LWS_VISIBLE LWS_EXTERN void |
156 | lws_log_use_cx_file(struct lws_log_cx *cx, int _new); |
157 | |
158 | LWS_VISIBLE LWS_EXTERN void |
159 | lws_log_prepend_context(struct lws_log_cx *cx, void *obj, char **p, char *e); |
160 | LWS_VISIBLE LWS_EXTERN void |
161 | lws_log_prepend_vhost(struct lws_log_cx *cx, void *obj, char **p, char *e); |
162 | LWS_VISIBLE LWS_EXTERN void |
163 | lws_log_prepend_wsi(struct lws_log_cx *cx, void *obj, char **p, char *e); |
164 | #if defined(LWS_WITH_SECURE_STREAMS) |
165 | LWS_VISIBLE LWS_EXTERN void |
166 | lws_log_prepend_ss(struct lws_log_cx *cx, void *obj, char **p, char *e); |
167 | LWS_VISIBLE LWS_EXTERN void |
168 | lws_log_prepend_sspc(struct lws_log_cx *cx, void *obj, char **p, char *e); |
169 | #endif |
170 | |
171 | LWS_VISIBLE LWS_EXTERN void |
172 | _lws_log_cx(lws_log_cx_t *cx, lws_log_prepend_cx_t prep, void *obj, |
173 | int filter, const char *_fun, const char *format, ...) LWS_FORMAT(6); |
174 | |
175 | #define lwsl_cx(_c, _fil, ...) \ |
176 | _lws_log_cx(lwsl_context_get_cx(_c), lws_log_prepend_context, \ |
177 | _c, _fil, __func__, __VA_ARGS__) |
178 | #define lwsl_vhost(_v, _fil, ...) \ |
179 | _lws_log_cx(lwsl_vhost_get_cx(_v), lws_log_prepend_vhost, _v, \ |
180 | _fil, __func__, __VA_ARGS__) |
181 | #define lwsl_wsi(_w, _fil, ...) \ |
182 | _lws_log_cx(lwsl_wsi_get_cx(_w), lws_log_prepend_wsi, _w, \ |
183 | _fil, __func__, __VA_ARGS__) |
184 | #define lwsl_ss(_h, _fil, ...) \ |
185 | _lws_log_cx(lwsl_ss_get_cx(_h), lws_log_prepend_ss, _h, \ |
186 | _fil, __func__, __VA_ARGS__) |
187 | |
188 | #define lwsl_hexdump_context(_c, _fil, _buf, _len) \ |
189 | lwsl_hexdump_level_cx(lwsl_context_get_cx(_c), \ |
190 | lws_log_prepend_context, \ |
191 | _c, _fil, _buf, _len) |
192 | #define lwsl_hexdump_vhost(_v, _fil, _buf, _len) \ |
193 | lwsl_hexdump_level_cx(lwsl_vhost_get_cx(_v), \ |
194 | lws_log_prepend_vhost, \ |
195 | _v, _fil, _buf, _len) |
196 | #define lwsl_hexdump_wsi(_w, _fil, _buf, _len) \ |
197 | lwsl_hexdump_level_cx(lwsl_wsi_get_cx(_w), \ |
198 | lws_log_prepend_wsi, \ |
199 | _w, _fil, _buf, _len) |
200 | #define lwsl_hexdump_ss(_h, _fil, _buf, _len) \ |
201 | lwsl_hexdump_level_cx(lwsl_ss_get_cx(_h), \ |
202 | lws_log_prepend_ss, \ |
203 | _h, _fil, _buf, _len) |
204 | |
205 | /* |
206 | * Figure out which logs to build in or not |
207 | */ |
208 | |
209 | #if defined(_DEBUG) |
210 | /* |
211 | * In DEBUG build, select all logs unless NO_LOGS |
212 | */ |
213 | #if defined(LWS_WITH_NO_LOGS) |
214 | #define _LWS_LINIT (LLL_ERR | LLL_USER) |
215 | #else |
216 | #define _LWS_LINIT ((1 << LLL_COUNT) - 1) |
217 | #endif |
218 | #else /* not _DEBUG */ |
219 | #if defined(LWS_WITH_NO_LOGS) |
220 | #define _LWS_LINIT (LLL_ERR | LLL_USER) |
221 | #else |
222 | #define _LWS_LINIT (LLL_ERR | LLL_USER | LLL_WARN | LLL_NOTICE) |
223 | #endif |
224 | #endif /* _DEBUG */ |
225 | |
226 | /* |
227 | * Create either empty overrides or the ones forced at build-time. |
228 | * These overrides have the final say... any bits set in |
229 | * LWS_LOGGING_BITFIELD_SET force the build of those logs, any bits |
230 | * set in LWS_LOGGING_BITFIELD_CLEAR disable the build of those logs. |
231 | * |
232 | * If not defined lws decides based on CMAKE_BUILD_TYPE=DEBUG or not |
233 | */ |
234 | |
235 | #if defined(LWS_LOGGING_BITFIELD_SET) |
236 | #define _LWS_LBS (LWS_LOGGING_BITFIELD_SET) |
237 | #else |
238 | #define _LWS_LBS 0 |
239 | #endif |
240 | |
241 | #if defined(LWS_LOGGING_BITFIELD_CLEAR) |
242 | #define _LWS_LBC (LWS_LOGGING_BITFIELD_CLEAR) |
243 | #else |
244 | #define _LWS_LBC 0 |
245 | #endif |
246 | |
247 | /* |
248 | * Compute the final active logging bitfield for build |
249 | */ |
250 | #define _LWS_ENABLED_LOGS (((_LWS_LINIT) | (_LWS_LBS)) & ~(_LWS_LBC)) |
251 | |
252 | /* |
253 | * Individually enable or disable log levels for build |
254 | * depending on what was computed |
255 | */ |
256 | |
257 | /* |
258 | * Process scope logs |
259 | */ |
260 | |
261 | #if (_LWS_ENABLED_LOGS & LLL_ERR) |
262 | #define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) |
263 | #else |
264 | #define lwsl_err(...) do {} while(0) |
265 | #endif |
266 | |
267 | #if (_LWS_ENABLED_LOGS & LLL_WARN) |
268 | #define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) |
269 | #else |
270 | #define lwsl_warn(...) do {} while(0) |
271 | #endif |
272 | |
273 | #if (_LWS_ENABLED_LOGS & LLL_NOTICE) |
274 | #define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) |
275 | #else |
276 | #define lwsl_notice(...) do {} while(0) |
277 | #endif |
278 | |
279 | #if (_LWS_ENABLED_LOGS & LLL_INFO) |
280 | #define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) |
281 | #else |
282 | #define lwsl_info(...) do {} while(0) |
283 | #endif |
284 | |
285 | #if (_LWS_ENABLED_LOGS & LLL_DEBUG) |
286 | #define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) |
287 | #else |
288 | #define lwsl_debug(...) do {} while(0) |
289 | #endif |
290 | |
291 | #if (_LWS_ENABLED_LOGS & LLL_PARSER) |
292 | #define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) |
293 | #else |
294 | #define lwsl_parser(...) do {} while(0) |
295 | #endif |
296 | |
297 | #if (_LWS_ENABLED_LOGS & LLL_HEADER) |
298 | #define (...) _lws_log(LLL_HEADER, __VA_ARGS__) |
299 | #else |
300 | #define lwsl_header(...) do {} while(0) |
301 | #endif |
302 | |
303 | #if (_LWS_ENABLED_LOGS & LLL_EXT) |
304 | #define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) |
305 | #else |
306 | #define lwsl_ext(...) do {} while(0) |
307 | #endif |
308 | |
309 | #if (_LWS_ENABLED_LOGS & LLL_CLIENT) |
310 | #define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) |
311 | #else |
312 | #define lwsl_client(...) do {} while(0) |
313 | #endif |
314 | |
315 | #if (_LWS_ENABLED_LOGS & LLL_LATENCY) |
316 | #define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) |
317 | #else |
318 | #define lwsl_latency(...) do {} while(0) |
319 | #endif |
320 | |
321 | #if (_LWS_ENABLED_LOGS & LLL_THREAD) |
322 | #define lwsl_thread(...) _lws_log(LLL_THREAD, __VA_ARGS__) |
323 | #else |
324 | #define lwsl_thread(...) do {} while(0) |
325 | #endif |
326 | |
327 | #if (_LWS_ENABLED_LOGS & LLL_USER) |
328 | #define lwsl_user(...) _lws_log(LLL_USER, __VA_ARGS__) |
329 | #else |
330 | #define lwsl_user(...) do {} while(0) |
331 | #endif |
332 | |
333 | #define lwsl_hexdump_err(...) lwsl_hexdump_level(LLL_ERR, __VA_ARGS__) |
334 | #define lwsl_hexdump_warn(...) lwsl_hexdump_level(LLL_WARN, __VA_ARGS__) |
335 | #define lwsl_hexdump_notice(...) lwsl_hexdump_level(LLL_NOTICE, __VA_ARGS__) |
336 | #define lwsl_hexdump_info(...) lwsl_hexdump_level(LLL_INFO, __VA_ARGS__) |
337 | #define lwsl_hexdump_debug(...) lwsl_hexdump_level(LLL_DEBUG, __VA_ARGS__) |
338 | |
339 | /* |
340 | * lws_context scope logs |
341 | */ |
342 | |
343 | #if (_LWS_ENABLED_LOGS & LLL_ERR) |
344 | #define lwsl_cx_err(_c, ...) lwsl_cx(_c, LLL_ERR, __VA_ARGS__) |
345 | #else |
346 | #define lwsl_cx_err(_c, ...) do {} while(0) |
347 | #endif |
348 | |
349 | #if (_LWS_ENABLED_LOGS & LLL_WARN) |
350 | #define lwsl_cx_warn(_c, ...) lwsl_cx(_c, LLL_WARN, __VA_ARGS__) |
351 | #else |
352 | #define lwsl_cx_warn(_c, ...) do {} while(0) |
353 | #endif |
354 | |
355 | #if (_LWS_ENABLED_LOGS & LLL_NOTICE) |
356 | #define lwsl_cx_notice(_c, ...) lwsl_cx(_c, LLL_NOTICE, __VA_ARGS__) |
357 | #else |
358 | #define lwsl_cx_notice(_c, ...) do {} while(0) |
359 | #endif |
360 | |
361 | #if (_LWS_ENABLED_LOGS & LLL_INFO) |
362 | #define lwsl_cx_info(_c, ...) lwsl_cx(_c, LLL_INFO, __VA_ARGS__) |
363 | #else |
364 | #define lwsl_cx_info(_c, ...) do {} while(0) |
365 | #endif |
366 | |
367 | #if (_LWS_ENABLED_LOGS & LLL_DEBUG) |
368 | #define lwsl_cx_debug(_c, ...) lwsl_cx(_c, LLL_DEBUG, __VA_ARGS__) |
369 | #else |
370 | #define lwsl_cx_debug(_c, ...) do {} while(0) |
371 | #endif |
372 | |
373 | #if (_LWS_ENABLED_LOGS & LLL_PARSER) |
374 | #define lwsl_cx_parser(_c, ...) lwsl_cx(_c, LLL_PARSER, __VA_ARGS__) |
375 | #else |
376 | #define lwsl_cx_parser(_c, ...) do {} while(0) |
377 | #endif |
378 | |
379 | #if (_LWS_ENABLED_LOGS & LLL_HEADER) |
380 | #define (_c, ...) lwsl_cx(_c, LLL_HEADER, __VA_ARGS__) |
381 | #else |
382 | #define lwsl_cx_header(_c, ...) do {} while(0) |
383 | #endif |
384 | |
385 | #if (_LWS_ENABLED_LOGS & LLL_EXT) |
386 | #define lwsl_cx_ext(_c, ...) lwsl_cx(_c, LLL_EXT, __VA_ARGS__) |
387 | #else |
388 | #define lwsl_cx_ext(_c, ...) do {} while(0) |
389 | #endif |
390 | |
391 | #if (_LWS_ENABLED_LOGS & LLL_CLIENT) |
392 | #define lwsl_cx_client(_c, ...) lwsl_cx(_c, LLL_CLIENT, __VA_ARGS__) |
393 | #else |
394 | #define lwsl_cx_client(_c, ...) do {} while(0) |
395 | #endif |
396 | |
397 | #if (_LWS_ENABLED_LOGS & LLL_LATENCY) |
398 | #define lwsl_cx_latency(_c, ...) lwsl_cx(_c, LLL_LATENCY, __VA_ARGS__) |
399 | #else |
400 | #define lwsl_cx_latency(_c, ...) do {} while(0) |
401 | #endif |
402 | |
403 | #if (_LWS_ENABLED_LOGS & LLL_THREAD) |
404 | #define lwsl_cx_thread(_c, ...) lwsl_cx(_c, LLL_THREAD, __VA_ARGS__) |
405 | #else |
406 | #define lwsl_cx_thread(_c, ...) do {} while(0) |
407 | #endif |
408 | |
409 | #if (_LWS_ENABLED_LOGS & LLL_USER) |
410 | #define lwsl_cx_user(_c, ...) lwsl_cx(_c, LLL_USER, __VA_ARGS__) |
411 | #else |
412 | #define lwsl_cx_user(_c, ...) do {} while(0) |
413 | #endif |
414 | |
415 | #define lwsl_hexdump_cx_err(_c, ...) lwsl_hexdump_context(_c, LLL_ERR, __VA_ARGS__) |
416 | #define lwsl_hexdump_cx_warn(_c, ...) lwsl_hexdump_context(_c, LLL_WARN, __VA_ARGS__) |
417 | #define lwsl_hexdump_cx_notice(_c, ...) lwsl_hexdump_context(_c, LLL_NOTICE, __VA_ARGS__) |
418 | #define lwsl_hexdump_cx_info(_c, ...) lwsl_hexdump_context(_c, LLL_INFO, __VA_ARGS__) |
419 | #define lwsl_hexdump_cx_debug(_c, ...) lwsl_hexdump_context(_c, LLL_DEBUG, __VA_ARGS__) |
420 | |
421 | /* |
422 | * lws_vhost |
423 | */ |
424 | |
425 | #if (_LWS_ENABLED_LOGS & LLL_ERR) |
426 | #define lwsl_vhost_err(_v, ...) lwsl_vhost(_v, LLL_ERR, __VA_ARGS__) |
427 | #else |
428 | #define lwsl_vhost_err(_v, ...) do {} while(0) |
429 | #endif |
430 | |
431 | #if (_LWS_ENABLED_LOGS & LLL_WARN) |
432 | #define lwsl_vhost_warn(_v, ...) lwsl_vhost(_v, LLL_WARN, __VA_ARGS__) |
433 | #else |
434 | #define lwsl_vhost_warn(_v, ...) do {} while(0) |
435 | #endif |
436 | |
437 | #if (_LWS_ENABLED_LOGS & LLL_NOTICE) |
438 | #define lwsl_vhost_notice(_v, ...) lwsl_vhost(_v, LLL_NOTICE, __VA_ARGS__) |
439 | #else |
440 | #define lwsl_vhost_notice(_v, ...) do {} while(0) |
441 | #endif |
442 | |
443 | #if (_LWS_ENABLED_LOGS & LLL_INFO) |
444 | #define lwsl_vhost_info(_v, ...) lwsl_vhost(_v, LLL_INFO, __VA_ARGS__) |
445 | #else |
446 | #define lwsl_vhost_info(_v, ...) do {} while(0) |
447 | #endif |
448 | |
449 | #if (_LWS_ENABLED_LOGS & LLL_DEBUG) |
450 | #define lwsl_vhost_debug(_v, ...) lwsl_vhost(_v, LLL_DEBUG, __VA_ARGS__) |
451 | #else |
452 | #define lwsl_vhost_debug(_v, ...) do {} while(0) |
453 | #endif |
454 | |
455 | #if (_LWS_ENABLED_LOGS & LLL_PARSER) |
456 | #define lwsl_vhost_parser(_v, ...) lwsl_vhost(_v, LLL_PARSER, __VA_ARGS__) |
457 | #else |
458 | #define lwsl_vhost_parser(_v, ...) do {} while(0) |
459 | #endif |
460 | |
461 | #if (_LWS_ENABLED_LOGS & LLL_HEADER) |
462 | #define (_v, ...) lwsl_vhost(_v, LLL_HEADER, __VA_ARGS__) |
463 | #else |
464 | #define lwsl_vhost_header(_v, ...) do {} while(0) |
465 | #endif |
466 | |
467 | #if (_LWS_ENABLED_LOGS & LLL_EXT) |
468 | #define lwsl_vhost_ext(_v, ...) lwsl_vhost(_v, LLL_EXT, __VA_ARGS__) |
469 | #else |
470 | #define lwsl_vhost_ext(_v, ...) do {} while(0) |
471 | #endif |
472 | |
473 | #if (_LWS_ENABLED_LOGS & LLL_CLIENT) |
474 | #define lwsl_vhost_client(_v, ...) lwsl_vhost(_v, LLL_CLIENT, __VA_ARGS__) |
475 | #else |
476 | #define lwsl_vhost_client(_v, ...) do {} while(0) |
477 | #endif |
478 | |
479 | #if (_LWS_ENABLED_LOGS & LLL_LATENCY) |
480 | #define lwsl_vhost_latency(_v, ...) lwsl_vhost(_v, LLL_LATENCY, __VA_ARGS__) |
481 | #else |
482 | #define lwsl_vhost_latency(_v, ...) do {} while(0) |
483 | #endif |
484 | |
485 | #if (_LWS_ENABLED_LOGS & LLL_THREAD) |
486 | #define lwsl_vhost_thread(_v, ...) lwsl_vhost(_v, LLL_THREAD, __VA_ARGS__) |
487 | #else |
488 | #define lwsl_vhost_thread(_v, ...) do {} while(0) |
489 | #endif |
490 | |
491 | #if (_LWS_ENABLED_LOGS & LLL_USER) |
492 | #define lwsl_vhost_user(_v, ...) lwsl_vhost(_v, LLL_USER, __VA_ARGS__) |
493 | #else |
494 | #define lwsl_vhost_user(_v, ...) do {} while(0) |
495 | #endif |
496 | |
497 | #define lwsl_hexdump_vhost_err(_v, ...) lwsl_hexdump_vhost(_v, LLL_ERR, __VA_ARGS__) |
498 | #define lwsl_hexdump_vhost_warn(_v, ...) lwsl_hexdump_vhost(_v, LLL_WARN, __VA_ARGS__) |
499 | #define lwsl_hexdump_vhost_notice(_v, ...) lwsl_hexdump_vhost(_v, LLL_NOTICE, __VA_ARGS__) |
500 | #define lwsl_hexdump_vhost_info(_v, ...) lwsl_hexdump_vhost(_v, LLL_INFO, __VA_ARGS__) |
501 | #define lwsl_hexdump_vhost_debug(_v, ...) lwsl_hexdump_vhost(_v, LLL_DEBUG, __VA_ARGS__) |
502 | |
503 | |
504 | /* |
505 | * lws_wsi |
506 | */ |
507 | |
508 | #if (_LWS_ENABLED_LOGS & LLL_ERR) |
509 | #define lwsl_wsi_err(_w, ...) lwsl_wsi(_w, LLL_ERR, __VA_ARGS__) |
510 | #else |
511 | #define lwsl_wsi_err(_w, ...) do {} while(0) |
512 | #endif |
513 | |
514 | #if (_LWS_ENABLED_LOGS & LLL_WARN) |
515 | #define lwsl_wsi_warn(_w, ...) lwsl_wsi(_w, LLL_WARN, __VA_ARGS__) |
516 | #else |
517 | #define lwsl_wsi_warn(_w, ...) do {} while(0) |
518 | #endif |
519 | |
520 | #if (_LWS_ENABLED_LOGS & LLL_NOTICE) |
521 | #define lwsl_wsi_notice(_w, ...) lwsl_wsi(_w, LLL_NOTICE, __VA_ARGS__) |
522 | #else |
523 | #define lwsl_wsi_notice(_w, ...) do {} while(0) |
524 | #endif |
525 | |
526 | #if (_LWS_ENABLED_LOGS & LLL_INFO) |
527 | #define lwsl_wsi_info(_w, ...) lwsl_wsi(_w, LLL_INFO, __VA_ARGS__) |
528 | #else |
529 | #define lwsl_wsi_info(_w, ...) do {} while(0) |
530 | #endif |
531 | |
532 | #if (_LWS_ENABLED_LOGS & LLL_DEBUG) |
533 | #define lwsl_wsi_debug(_w, ...) lwsl_wsi(_w, LLL_DEBUG, __VA_ARGS__) |
534 | #else |
535 | #define lwsl_wsi_debug(_w, ...) do {} while(0) |
536 | #endif |
537 | |
538 | #if (_LWS_ENABLED_LOGS & LLL_PARSER) |
539 | #define lwsl_wsi_parser(_w, ...) lwsl_wsi(_w, LLL_PARSER, __VA_ARGS__) |
540 | #else |
541 | #define lwsl_wsi_parser(_w, ...) do {} while(0) |
542 | #endif |
543 | |
544 | #if (_LWS_ENABLED_LOGS & LLL_HEADER) |
545 | #define (_w, ...) lwsl_wsi(_w, LLL_HEADER, __VA_ARGS__) |
546 | #else |
547 | #define lwsl_wsi_header(_w, ...) do {} while(0) |
548 | #endif |
549 | |
550 | #if (_LWS_ENABLED_LOGS & LLL_EXT) |
551 | #define lwsl_wsi_ext(_w, ...) lwsl_wsi(_w, LLL_EXT, __VA_ARGS__) |
552 | #else |
553 | #define lwsl_wsi_ext(_w, ...) do {} while(0) |
554 | #endif |
555 | |
556 | #if (_LWS_ENABLED_LOGS & LLL_CLIENT) |
557 | #define lwsl_wsi_client(_w, ...) lwsl_wsi(_w, LLL_CLIENT, __VA_ARGS__) |
558 | #else |
559 | #define lwsl_wsi_client(_w, ...) do {} while(0) |
560 | #endif |
561 | |
562 | #if (_LWS_ENABLED_LOGS & LLL_LATENCY) |
563 | #define lwsl_wsi_latency(_w, ...) lwsl_wsi(_w, LLL_LATENCY, __VA_ARGS__) |
564 | #else |
565 | #define lwsl_wsi_latency(_w, ...) do {} while(0) |
566 | #endif |
567 | |
568 | #if (_LWS_ENABLED_LOGS & LLL_THREAD) |
569 | #define lwsl_wsi_thread(_w, ...) lwsl_wsi(_w, LLL_THREAD, __VA_ARGS__) |
570 | #else |
571 | #define lwsl_wsi_thread(_w, ...) do {} while(0) |
572 | #endif |
573 | |
574 | #if (_LWS_ENABLED_LOGS & LLL_USER) |
575 | #define lwsl_wsi_user(_w, ...) lwsl_wsi(_w, LLL_USER, __VA_ARGS__) |
576 | #else |
577 | #define lwsl_wsi_user(_w, ...) do {} while(0) |
578 | #endif |
579 | |
580 | #define lwsl_hexdump_wsi_err(_v, ...) lwsl_hexdump_wsi(_v, LLL_ERR, __VA_ARGS__) |
581 | #define lwsl_hexdump_wsi_warn(_v, ...) lwsl_hexdump_wsi(_v, LLL_WARN, __VA_ARGS__) |
582 | #define lwsl_hexdump_wsi_notice(_v, ...) lwsl_hexdump_wsi(_v, LLL_NOTICE, __VA_ARGS__) |
583 | #define lwsl_hexdump_wsi_info(_v, ...) lwsl_hexdump_wsi(_v, LLL_INFO, __VA_ARGS__) |
584 | #define lwsl_hexdump_wsi_debug(_v, ...) lwsl_hexdump_wsi(_v, LLL_DEBUG, __VA_ARGS__) |
585 | |
586 | |
587 | /* |
588 | * lwsl_ss |
589 | */ |
590 | |
591 | #if (_LWS_ENABLED_LOGS & LLL_ERR) |
592 | #define lwsl_ss_err(_w, ...) lwsl_ss(_w, LLL_ERR, __VA_ARGS__) |
593 | #else |
594 | #define lwsl_ss_err(_w, ...) do {} while(0) |
595 | #endif |
596 | |
597 | #if (_LWS_ENABLED_LOGS & LLL_WARN) |
598 | #define lwsl_ss_warn(_w, ...) lwsl_ss(_w, LLL_WARN, __VA_ARGS__) |
599 | #else |
600 | #define lwsl_ss_warn(_w, ...) do {} while(0) |
601 | #endif |
602 | |
603 | #if (_LWS_ENABLED_LOGS & LLL_NOTICE) |
604 | #define lwsl_ss_notice(_w, ...) lwsl_ss(_w, LLL_NOTICE, __VA_ARGS__) |
605 | #else |
606 | #define lwsl_ss_notice(_w, ...) do {} while(0) |
607 | #endif |
608 | |
609 | #if (_LWS_ENABLED_LOGS & LLL_INFO) |
610 | #define lwsl_ss_info(_w, ...) lwsl_ss(_w, LLL_INFO, __VA_ARGS__) |
611 | #else |
612 | #define lwsl_ss_info(_w, ...) do {} while(0) |
613 | #endif |
614 | |
615 | #if (_LWS_ENABLED_LOGS & LLL_DEBUG) |
616 | #define lwsl_ss_debug(_w, ...) lwsl_ss(_w, LLL_DEBUG, __VA_ARGS__) |
617 | #else |
618 | #define lwsl_ss_debug(_w, ...) do {} while(0) |
619 | #endif |
620 | |
621 | #if (_LWS_ENABLED_LOGS & LLL_PARSER) |
622 | #define lwsl_ss_parser(_w, ...) lwsl_ss(_w, LLL_PARSER, __VA_ARGS__) |
623 | #else |
624 | #define lwsl_ss_parser(_w, ...) do {} while(0) |
625 | #endif |
626 | |
627 | #if (_LWS_ENABLED_LOGS & LLL_HEADER) |
628 | #define (_w, ...) lwsl_ss(_w, LLL_HEADER, __VA_ARGS__) |
629 | #else |
630 | #define lwsl_ss_header(_w, ...) do {} while(0) |
631 | #endif |
632 | |
633 | #if (_LWS_ENABLED_LOGS & LLL_EXT) |
634 | #define lwsl_ss_ext(_w, ...) lwsl_ss(_w, LLL_EXT, __VA_ARGS__) |
635 | #else |
636 | #define lwsl_ss_ext(_w, ...) do {} while(0) |
637 | #endif |
638 | |
639 | #if (_LWS_ENABLED_LOGS & LLL_CLIENT) |
640 | #define lwsl_ss_client(_w, ...) lwsl_ss(_w, LLL_CLIENT, __VA_ARGS__) |
641 | #else |
642 | #define lwsl_ss_client(_w, ...) do {} while(0) |
643 | #endif |
644 | |
645 | #if (_LWS_ENABLED_LOGS & LLL_LATENCY) |
646 | #define lwsl_ss_latency(_w, ...) lwsl_ss(_w, LLL_LATENCY, __VA_ARGS__) |
647 | #else |
648 | #define lwsl_ss_latency(_w, ...) do {} while(0) |
649 | #endif |
650 | |
651 | #if (_LWS_ENABLED_LOGS & LLL_THREAD) |
652 | #define lwsl_ss_thread(_w, ...) lwsl_ss(_w, LLL_THREAD, __VA_ARGS__) |
653 | #else |
654 | #define lwsl_ss_thread(_w, ...) do {} while(0) |
655 | #endif |
656 | |
657 | #if (_LWS_ENABLED_LOGS & LLL_USER) |
658 | #define lwsl_ss_user(_w, ...) lwsl_ss(_w, LLL_USER, __VA_ARGS__) |
659 | #else |
660 | #define lwsl_ss_user(_w, ...) do {} while(0) |
661 | #endif |
662 | |
663 | #define lwsl_hexdump_ss_err(_v, ...) lwsl_hexdump_ss(_v, LLL_ERR, __VA_ARGS__) |
664 | #define lwsl_hexdump_ss_warn(_v, ...) lwsl_hexdump_ss(_v, LLL_WARN, __VA_ARGS__) |
665 | #define lwsl_hexdump_ss_notice(_v, ...) lwsl_hexdump_ss(_v, LLL_NOTICE, __VA_ARGS__) |
666 | #define lwsl_hexdump_ss_info(_v, ...) lwsl_hexdump_ss(_v, LLL_INFO, __VA_ARGS__) |
667 | #define lwsl_hexdump_ss_debug(_v, ...) lwsl_hexdump_ss(_v, LLL_DEBUG, __VA_ARGS__) |
668 | |
669 | |
670 | |
671 | /** |
672 | * lwsl_hexdump_level() - helper to hexdump a buffer at a selected debug level |
673 | * |
674 | * \param level: one of LLL_ constants |
675 | * \param vbuf: buffer start to dump |
676 | * \param len: length of buffer to dump |
677 | * |
678 | * If \p level is visible, does a nice hexdump -C style dump of \p vbuf for |
679 | * \p len bytes. This can be extremely convenient while debugging. |
680 | */ |
681 | LWS_VISIBLE LWS_EXTERN void |
682 | lwsl_hexdump_level(int level, const void *vbuf, size_t len); |
683 | |
684 | LWS_VISIBLE LWS_EXTERN void |
685 | lwsl_hexdump_level_cx(lws_log_cx_t *cx, lws_log_prepend_cx_t prep, void *obj, |
686 | int hexdump_level, const void *vbuf, size_t len); |
687 | |
688 | /** |
689 | * lwsl_hexdump() - helper to hexdump a buffer (DEBUG builds only) |
690 | * |
691 | * \param buf: buffer start to dump |
692 | * \param len: length of buffer to dump |
693 | * |
694 | * Calls through to lwsl_hexdump_level(LLL_DEBUG, ... for compatability. |
695 | * It's better to use lwsl_hexdump_level(level, ... directly so you can control |
696 | * the visibility. |
697 | */ |
698 | LWS_VISIBLE LWS_EXTERN void |
699 | lwsl_hexdump(const void *buf, size_t len); |
700 | |
701 | /** |
702 | * lws_is_be() - returns nonzero if the platform is Big Endian |
703 | */ |
704 | static LWS_INLINE int lws_is_be(void) { |
705 | const int probe = ~0xff; |
706 | |
707 | return *(const char *)&probe; |
708 | } |
709 | |
710 | /** |
711 | * lws_set_log_level() - Set the logging bitfield |
712 | * \param level: OR together the LLL_ debug contexts you want output from |
713 | * \param log_emit_function: NULL to leave it as it is, or a user-supplied |
714 | * function to perform log string emission instead of |
715 | * the default stderr one. |
716 | * |
717 | * log level defaults to "err", "warn" and "notice" contexts enabled and |
718 | * emission on stderr. If stderr is a tty (according to isatty()) then |
719 | * the output is coloured according to the log level using ANSI escapes. |
720 | * |
721 | * You can set the default security level for logging using the |
722 | * secrecy_and_log_level() macro to set the \p level parameter, eg |
723 | * |
724 | * lws_set_log_level(secrecy_and_log_level(LWS_SECRECY_PII, LLL_ERR | LLL_WARN), |
725 | * my_emit_function); |
726 | * |
727 | * Normally you can just leave it at the default. |
728 | */ |
729 | LWS_VISIBLE LWS_EXTERN void |
730 | lws_set_log_level(int level, lws_log_emit_t log_emit_function); |
731 | |
732 | /** |
733 | * lwsl_emit_syslog() - helper log emit function writes to system log |
734 | * |
735 | * \param level: one of LLL_ log level indexes |
736 | * \param line: log string |
737 | * |
738 | * You use this by passing the function pointer to lws_set_log_level(), to set |
739 | * it as the log emit function, it is not called directly. |
740 | */ |
741 | LWS_VISIBLE LWS_EXTERN void |
742 | lwsl_emit_syslog(int level, const char *line); |
743 | |
744 | /** |
745 | * lwsl_emit_stderr() - helper log emit function writes to stderr |
746 | * |
747 | * \param level: one of LLL_ log level indexes |
748 | * \param line: log string |
749 | * |
750 | * You use this by passing the function pointer to lws_set_log_level(), to set |
751 | * it as the log emit function, it is not called directly. |
752 | * |
753 | * It prepends a system timestamp like [2018/11/13 07:41:57:3989] |
754 | * |
755 | * If stderr is a tty, then ansi colour codes are added. |
756 | */ |
757 | LWS_VISIBLE LWS_EXTERN void |
758 | lwsl_emit_stderr(int level, const char *line); |
759 | |
760 | /** |
761 | * lwsl_emit_stderr_notimestamp() - helper log emit function writes to stderr |
762 | * |
763 | * \param level: one of LLL_ log level indexes |
764 | * \param line: log string |
765 | * |
766 | * You use this by passing the function pointer to lws_set_log_level(), to set |
767 | * it as the log emit function, it is not called directly. |
768 | * |
769 | * If stderr is a tty, then ansi colour codes are added. |
770 | */ |
771 | LWS_VISIBLE LWS_EXTERN void |
772 | lwsl_emit_stderr_notimestamp(int level, const char *line); |
773 | |
774 | /** |
775 | * lwsl_visible() - returns true if the log level should be printed |
776 | * |
777 | * \param level: one of LLL_ log level indexes |
778 | * |
779 | * This is useful if you have to do work to generate the log content, you |
780 | * can skip the work if the log level used to print it is not actually |
781 | * enabled at runtime. |
782 | */ |
783 | LWS_VISIBLE LWS_EXTERN int |
784 | lwsl_visible(int level); |
785 | |
786 | struct lws; |
787 | |
788 | LWS_VISIBLE LWS_EXTERN const char * |
789 | lws_wsi_tag(struct lws *wsi); |
790 | |
791 | LWS_VISIBLE LWS_EXTERN void |
792 | lwsl_refcount_cx(lws_log_cx_t *cx, int _new); |
793 | |
794 | ///@} |
795 | |