blob: 090d1aae8a208bf1d7c6fda5e3cdbfe794db5822 [file] [log] [blame]
Radek Krejci5aeea3a2018-09-05 13:29:36 +02001/**
2 * @file log.h
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief Logger manipulation routines and error definitions.
5 *
6 * Copyright (c) 2015 - 2018 CESNET, z.s.p.o.
7 *
8 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * https://opensource.org/licenses/BSD-3-Clause
13 */
14
15#ifndef LY_LOG_H_
16#define LY_LOG_H_
17
Radek Krejci1deb5be2020-08-26 16:43:36 +020018#include <stdint.h>
19
Radek Krejci5aeea3a2018-09-05 13:29:36 +020020#ifdef __cplusplus
21extern "C" {
22#endif
23
Radek Krejciad573502018-09-07 15:26:55 +020024/* dummy context structure */
25struct ly_ctx;
26
Radek Krejci5aeea3a2018-09-05 13:29:36 +020027/**
Radek Krejci857189e2020-09-01 13:26:36 +020028 * @brief Type to indicate boolean value.
29 *
30 * Do not test for actual value. Instead, handle it as true/false value in condition.
31 */
32typedef uint8_t ly_bool;
33
34/**
Radek Krejci8678fa42020-08-18 16:07:28 +020035 * @page howtoLogger Information Logging
36 *
37 * The libyang logger is supposed to process all the messages (and some other accompanied information) generated by the performed
38 * functions. According to the logger settings, the information can be printed, stored or further processed by a callback
39 * functions.
40 *
41 * The logger is tightly connected with [errors handling](@ref howtoErrors), because when an error appears, the logger (according
42 * to [logger options](@ref logopts)) generates error records available via libyang context.
43 *
44 * There are 4 verbosity levels defined as ::LY_LOG_LEVEL. The level can be changed by the ::ly_log_level() function.
45 * By default, the verbosity level is set to #LY_LLERR value, so only the errors are processed.
46 *
47 * By default, all libyang messages are printed to `stderr`. However, the callers are able to set their own logging callback
48 * function (::ly_log_clb). In that case, instead of printing messages, libyang passes error level, message and path (if any) to
49 * the caller's callback function set via ::ly_set_log_clb(). In case of error level, the error information is still
50 * automatically stored and available via the [error handling functions](@ref howtoErrors).
51 *
52 * With [logging options](@ref logopts) set via ::ly_log_options(), the caller can modify what is done with all the messages.
53 * Default flags are ::LY_LOLOG and ::LY_LOSTORE_LAST so that messages are logged and the last one is stored. If you set the flag
54 * ::LY_LOSTORE, all the messages will be stored. Be careful because unless you regularly clean them, the error list in context
55 * will grow indefinitely.
56 *
57 * As a separate group, there are @ref dbggroup to select group of debugging messages to print. The options can be set via
58 * ::ly_log_dbg_groups() function, but note that the options take effect only in case the libyang is compiled in
Radek Krejci7132fc52020-10-26 14:34:06 +010059 * [Debug build mode](@ref build).
Radek Krejci8678fa42020-08-18 16:07:28 +020060 *
61 * \note API for this group of functions is described in the [logger module](@ref log).
62 *
63 * Functions List
64 * --------------
65 * - ::ly_log_level()
66 * - ::ly_log_dbg_groups()
67 * - ::ly_log_options()
68 * - ::ly_set_log_clb()
69 * - ::ly_get_log_clb()
70 *
71 */
72
73/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +020074 * @defgroup log Logger
75 * @{
76 *
77 * Publicly visible functions and values of the libyang logger. For more
Radek Krejci8678fa42020-08-18 16:07:28 +020078 * information, see \ref howtoLogger.
Radek Krejci5aeea3a2018-09-05 13:29:36 +020079 */
80
81/**
82 * @typedef LY_LOG_LEVEL
83 * @brief Verbosity levels of the libyang logger.
84 */
85typedef enum
86{
87 LY_LLERR = 0, /**< Print only error messages, default value. */
88 LY_LLWRN = 1, /**< Print error and warning messages. */
89 LY_LLVRB = 2, /**< Besides errors and warnings, print some other verbose messages. */
90 LY_LLDBG = 3 /**< Print all messages including some development debug messages (be careful,
Radek Krejci8678fa42020-08-18 16:07:28 +020091 without subsequently calling ::ly_log_dbg_groups() no debug messages will be printed!). */
Radek Krejci5aeea3a2018-09-05 13:29:36 +020092} LY_LOG_LEVEL;
93
94/**
95 * @brief Set logger verbosity level.
Radek Krejciebdaed02020-11-09 13:05:06 +010096 *
97 * To get the current value, the function must be called twice resetting the level by the reived value.
98 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +020099 * @param[in] level Verbosity level.
100 * @return Previous verbosity level.
101 */
Radek Krejci52b6d512020-10-12 12:33:17 +0200102LY_LOG_LEVEL ly_log_level(LY_LOG_LEVEL level);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200103
104/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200105 * @ingroup logger
Radek Krejci8678fa42020-08-18 16:07:28 +0200106 * @defgroup logopts Logging options
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200107 *
108 * Logging option bits of libyang.
109 *
Radek Krejci8678fa42020-08-18 16:07:28 +0200110 * Can be set via ::ly_log_options().
111 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200112 * @{
113 */
114#define LY_LOLOG 0x01 /**< Log messages normally, using callback if set. If not set, messages will
115 not be printed by libyang. */
116#define LY_LOSTORE 0x02 /**< Store any generated errors or warnings, never verbose or debug messages.
117 Note that if #LY_LOLOG is not set then verbose and debug messages are always lost. */
118#define LY_LOSTORE_LAST 0x06 /**< Store any generated errors or warnings but only the last message, always overwrite
119 the previous one. */
120
121/**
122 * @}
123 */
124
125/**
Radek Krejci8678fa42020-08-18 16:07:28 +0200126 * @brief Set logger options. Default is #LY_LOLOG | #LY_LOSTORE_LAST.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200127 *
Radek Krejciebdaed02020-11-09 13:05:06 +0100128 * To get the current value, the function must be called twice resetting the level by the reived value.
129 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200130 * @param[in] opts Bitfield of @ref logopts.
131 * @return Previous logger options.
132 */
Radek Krejci1deb5be2020-08-26 16:43:36 +0200133uint32_t ly_log_options(uint32_t opts);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200134
135#ifndef NDEBUG
136
137/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200138 * @ingroup log
Radek Krejci8678fa42020-08-18 16:07:28 +0200139 * @defgroup dbggroup Debug messages groups
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200140 *
Radek Krejci8678fa42020-08-18 16:07:28 +0200141 * Categories of the debug messages.
142 *
143 * Allows to show only the selected group(s) of the debug messages.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200144 *
145 * @{
146 */
147
148#define LY_LDGDICT 0x01 /**< Dictionary additions and deletions. */
Radek Krejciebdaed02020-11-09 13:05:06 +0100149#define LY_LDGXPATH 0x02 /**< XPath parsing end evaluation. */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200150
151/**
152 * @}
153 */
154
155/**
156 * @brief Enable specific debugging messages (independent of log level).
Radek Krejciebdaed02020-11-09 13:05:06 +0100157 *
158 * To get the current value, the function must be called twice resetting the level by the reived value.
159 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200160 * @param[in] dbg_groups Bitfield of enabled debug message groups (see @ref dbggroup).
Radek Krejciebdaed02020-11-09 13:05:06 +0100161 * @return Previous options bitfield.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200162 */
Radek Krejciebdaed02020-11-09 13:05:06 +0100163uint32_t ly_log_dbg_groups(uint32_t dbg_groups);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200164
165#endif
166
167/**
Michal Vaskod8085612020-08-21 12:55:23 +0200168 * @brief Logger callback.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200169 *
170 * !IMPORTANT! If an error has a specific error-app-tag defined in the model, it will NOT be set
171 * at the time of calling this callback. It will be set right after, so to retrieve it
Radek Krejci8678fa42020-08-18 16:07:28 +0200172 * it must be checked afterwards with ::ly_errapptag().
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200173 *
Michal Vaskod8085612020-08-21 12:55:23 +0200174 * @param[in] level Log level of the message.
175 * @param[in] msg Message.
176 * @param[in] path Optional path of the concerned node.
177 */
178typedef void (*ly_log_clb)(LY_LOG_LEVEL level, const char *msg, const char *path);
179
180/**
181 * @brief Set logger callback.
182 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200183 * @param[in] clb Logging callback.
184 * @param[in] path flag to resolve and provide path as the third parameter of the callback function. In case of
185 * validation and some other errors, it can be useful to get the path to the problematic element. Note,
186 * that according to the tree type and the specific situation, the path can slightly differs (keys
187 * presence) or it can be NULL, so consider it as an optional parameter. If the flag is 0, libyang will
188 * not bother with resolving the path.
189 */
Radek Krejci857189e2020-09-01 13:26:36 +0200190void ly_set_log_clb(ly_log_clb clb, ly_bool path);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200191
192/**
193 * @brief Get logger callback.
194 * @return Logger callback (can be NULL).
195 */
Michal Vaskod8085612020-08-21 12:55:23 +0200196ly_log_clb ly_get_log_clb(void);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200197
198/** @} log */
199
200/**
Radek Krejci8678fa42020-08-18 16:07:28 +0200201 * @page howtoErrors Errors Handling
202 *
203 * The most of the API functions directly returns error code in the form of ::LY_ERR value. In addition, if the ::LY_EVALID error
204 * arises, additional [validation error code](@ref ::LY_VECODE) is provided to categorize validation failures into several groups.
205 *
206 * All the errors arisen in connection with manipulation with the [context](@ref howtoContext), [YANG modules](@ref howtoSchema)
207 * or [YANG data](@ref howtoData), are recorded into the context and can be examined for the more detailed information. These
208 * records are stored as ::ly_err_item structures and they are not only context-specific, but also thread-specific.
209 *
210 * Storing error information is tightly connected with
211 * [logging](@ref howtoLogger). So the @ref logopts control if and which errors are stored in the context. By default, only the
212 * last error is recorded, so a new error replaces the previous one. This can be changed with ::LY_LOSTORE option set via
213 * ::ly_log_options(). Then, the errors are stored as a list preserving the previous error records. The stored records can be
214 * accessed using ::ly_err_last() or ::ly_err_first() functions. The ::ly_err_clean() is used to remove error records from the
215 * context.
216 *
217 * To print a specific error information via libyang logger, there is ::ly_err_print().
218 *
219 * To simplify access to the last error record in the context, there is a set of functions returning important error information.
220 * - ::ly_errapptag()
221 * - ::ly_errcode()
222 * - ::ly_vecode()
223 * - ::ly_errmsg()
224 * - ::ly_errpath()
225 *
226 * \note API for this group of functions is described in the [error information module](@ref errors).
227 */
228
229/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200230 * @defgroup errors Error information
Radek Krejci8678fa42020-08-18 16:07:28 +0200231 *
232 * Structures and functions to allow error information processing.
233 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200234 * @{
235 */
236
237/**
238 * @typedef LY_ERR
239 * @brief libyang's error codes returned by the libyang functions.
240 */
241typedef enum
242{
243 LY_SUCCESS = 0, /**< no error, not set by functions, included just to complete #LY_ERR enumeration */
244 LY_EMEM, /**< Memory allocation failure */
Radek Krejcidc1c7e72018-09-07 14:58:20 +0200245 LY_ESYS, /**< System call failure */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200246 LY_EINVAL, /**< Invalid value */
247 LY_EEXIST, /**< Item already exists */
Radek Krejcid33273d2018-10-25 14:55:52 +0200248 LY_ENOTFOUND, /**< Item does not exists */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200249 LY_EINT, /**< Internal error */
250 LY_EVALID, /**< Validation failure */
Radek Krejcid3ca0632019-04-16 16:54:54 +0200251 LY_EDENIED, /**< Operation is not allowed */
Radek Krejcie553e6d2019-06-07 15:33:18 +0200252 LY_EINCOMPLETE, /**< The operation did not failed, but for some reason it was not possible to finish it completely.
253 According to the specific use case, the caller is usually supposed to perform the operation again. */
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200254 LY_ENOT, /**< Negative result */
Radek Krejcia4614e62020-05-15 14:19:28 +0200255 LY_EOTHER, /**< Unknown error */
256
257 LY_EPLUGIN = 128/**< Error reported by a plugin - the highest bit in the first byte is set.
258 This value is used ORed with one of the other LY_ERR value and can be simply masked. */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200259} LY_ERR;
260
261/**
Radek Krejci8678fa42020-08-18 16:07:28 +0200262 * @ingroup logger
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200263 * @typedef LY_VECODE
264 * @brief libyang's codes of validation error. Whenever ly_errno is set to LY_EVALID, the ly_vecode is also set
265 * to the appropriate LY_VECODE value.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200266 */
267typedef enum {
268 LYVE_SUCCESS = 0, /**< no error */
Radek Krejci94aa9942018-09-07 17:12:17 +0200269 LYVE_SYNTAX, /**< generic syntax error */
270 LYVE_SYNTAX_YANG, /**< YANG-related syntax error */
David Sedlák0a875b42019-03-07 22:24:05 +0100271 LYVE_SYNTAX_YIN, /**< YIN-related syntax error */
Radek Krejci70853c52018-10-15 14:46:16 +0200272 LYVE_REFERENCE, /**< invalid referencing or using an item */
Radek Krejcib1646a92018-11-02 16:08:26 +0100273 LYVE_XPATH, /**< invalid XPath expression */
Radek Krejcie7b95092019-05-15 11:03:07 +0200274 LYVE_SEMANTICS, /**< generic semantic error */
275 LYVE_SYNTAX_XML, /**< XML-related syntax error */
Radek Krejci1798aae2020-07-14 13:26:06 +0200276 LYVE_SYNTAX_JSON, /**< JSON-related syntax error */
Michal Vaskoecd62de2019-11-13 12:35:11 +0100277 LYVE_DATA, /**< YANG data does not reflect some of the module restrictions */
Radek Krejcia4614e62020-05-15 14:19:28 +0200278
279 LYVE_OTHER /**< Unknown error */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200280} LY_VECODE;
281
282/**
283 * @brief Libyang full error structure.
284 */
285struct ly_err_item {
286 LY_LOG_LEVEL level;
287 LY_ERR no;
288 LY_VECODE vecode;
289 char *msg;
290 char *path;
291 char *apptag;
292 struct ly_err_item *next;
293 struct ly_err_item *prev; /* first item's prev points to the last item */
294};
295
296/**
297 * @brief Get the last (thread, context-specific) validation error code.
298 *
299 * This value is set only if ly_errno is #LY_EVALID.
300 *
301 * @param[in] ctx Relative context.
302 * @return Validation error code.
303 */
304LY_VECODE ly_vecode(const struct ly_ctx *ctx);
305
306/**
Radek Krejcid33273d2018-10-25 14:55:52 +0200307 * @brief Get the last (thread, context-specific) error code.
308 *
309 * @param[in] ctx Relative context.
310 * @return LY_ERR value of the last error code.
311 */
312LY_ERR ly_errcode(const struct ly_ctx *ctx);
313
314/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200315 * @brief Get the last (thread, context-specific) error message. If the coresponding module defined
316 * a specific error message, it will be used instead the default one.
317 *
318 * Sometimes, the error message is extended with path of the element where the problem is.
Radek Krejci8678fa42020-08-18 16:07:28 +0200319 * The path is available via ::ly_errpath().
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200320 *
321 * @param[in] ctx Relative context.
322 * @return Text of the last error message, empty string if there is no error.
323 */
324const char *ly_errmsg(const struct ly_ctx *ctx);
325
326/**
327 * @brief Get the last (thread, context-specific) path of the element where was an error.
328 *
Radek Krejci8678fa42020-08-18 16:07:28 +0200329 * The path always corresponds to the error message available via ::ly_errmsg(), so
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200330 * whenever a subsequent error message is printed, the path is erased or rewritten.
331 * The path reflects the type of the processed tree - data path for data tree functions
332 * and schema path in case of schema tree functions. In case of processing YIN schema
333 * or XML data, the path can be just XML path. In such a case, the corresponding
334 * ly_vecode (value 1-3) is set.
335 *
336 * @param[in] ctx Relative context.
337 * @return Path of the error element, empty string if error path does not apply to the last error.
338 */
339const char *ly_errpath(const struct ly_ctx *ctx);
340
341/**
342 * @brief Get the last (thread, context-specific) error-app-tag if there was a specific one defined
343 * in the module for the last error.
344 *
Radek Krejci8678fa42020-08-18 16:07:28 +0200345 * The app-tag always corresponds to the error message available via ::ly_errmsg(), so
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200346 * whenever a subsequent error message is printed, the app-tag is erased or rewritten.
347 *
348 * @param[in] ctx Relative context.
349 * @return Error-app-tag of the last error, empty string if the error-app-tag does not apply to the last error.
350 */
351const char *ly_errapptag(const struct ly_ctx *ctx);
352
353/**
354 * @brief Get the first (thread, context-specific) generated error structure.
355 *
356 * @param[in] ctx Relative context.
Radek Krejci572ee602020-09-16 14:35:08 +0200357 * @return The first error structure (can be NULL), do not modify!
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200358 */
359struct ly_err_item *ly_err_first(const struct ly_ctx *ctx);
360
361/**
Radek Krejci572ee602020-09-16 14:35:08 +0200362 * @brief Get the latest (thread, context-specific) generated error structure.
363 *
364 * @param[in] ctx Relative context.
365 * @return The last error structure (can be NULL), do not modify!
366 */
367struct ly_err_item *ly_err_last(const struct ly_ctx *ctx);
368
369/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200370 * @brief Print the error structure as if just generated.
371 *
Michal Vasko177d0ed2020-11-23 16:43:03 +0100372 * @param[in] ctx Optional context to store the message in.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200373 * @param[in] eitem Error item structure to print.
374 */
Michal Vasko177d0ed2020-11-23 16:43:03 +0100375void ly_err_print(const struct ly_ctx *ctx, struct ly_err_item *eitem);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200376
377/**
378 * @brief Free error structures from a context.
379 *
380 * If \p eitem is not set, free all the error structures.
381 *
382 * @param[in] ctx Relative context.
383 * @param[in] eitem Oldest error structure to remove, optional.
384 */
385void ly_err_clean(struct ly_ctx *ctx, struct ly_err_item *eitem);
386
387/** @} errors */
388
389#ifdef __cplusplus
390}
391#endif
392
393#endif /* LY_LOG_H_ */