blob: 1766fbefc6b59dd72c07d0c1fc1ca27b03de0341 [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
59 * [Debug build mode](@ref building).
60 *
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.
96 * @param[in] level Verbosity level.
97 * @return Previous verbosity level.
98 */
Radek Krejci52b6d512020-10-12 12:33:17 +020099LY_LOG_LEVEL ly_log_level(LY_LOG_LEVEL level);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200100
101/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200102 * @ingroup logger
Radek Krejci8678fa42020-08-18 16:07:28 +0200103 * @defgroup logopts Logging options
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200104 *
105 * Logging option bits of libyang.
106 *
Radek Krejci8678fa42020-08-18 16:07:28 +0200107 * Can be set via ::ly_log_options().
108 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200109 * @{
110 */
111#define LY_LOLOG 0x01 /**< Log messages normally, using callback if set. If not set, messages will
112 not be printed by libyang. */
113#define LY_LOSTORE 0x02 /**< Store any generated errors or warnings, never verbose or debug messages.
114 Note that if #LY_LOLOG is not set then verbose and debug messages are always lost. */
115#define LY_LOSTORE_LAST 0x06 /**< Store any generated errors or warnings but only the last message, always overwrite
116 the previous one. */
117
118/**
119 * @}
120 */
121
122/**
Radek Krejci8678fa42020-08-18 16:07:28 +0200123 * @brief Set logger options. Default is #LY_LOLOG | #LY_LOSTORE_LAST.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200124 *
125 * @param[in] opts Bitfield of @ref logopts.
126 * @return Previous logger options.
127 */
Radek Krejci1deb5be2020-08-26 16:43:36 +0200128uint32_t ly_log_options(uint32_t opts);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200129
130#ifndef NDEBUG
131
132/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200133 * @ingroup log
Radek Krejci8678fa42020-08-18 16:07:28 +0200134 * @defgroup dbggroup Debug messages groups
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200135 *
Radek Krejci8678fa42020-08-18 16:07:28 +0200136 * Categories of the debug messages.
137 *
138 * Allows to show only the selected group(s) of the debug messages.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200139 *
140 * @{
141 */
142
143#define LY_LDGDICT 0x01 /**< Dictionary additions and deletions. */
144#define LY_LDGYANG 0x02 /**< YANG parser messages. */
145#define LY_LDGYIN 0x04 /**< YIN parser messages. */
146#define LY_LDGXPATH 0x08 /**< XPath parsing end evaluation. */
147#define LY_LDGDIFF 0x10 /**< Diff processing and creation. */
148
149/**
150 * @}
151 */
152
153/**
154 * @brief Enable specific debugging messages (independent of log level).
155 * @param[in] dbg_groups Bitfield of enabled debug message groups (see @ref dbggroup).
156 */
Radek Krejci68433c92020-10-12 17:03:55 +0200157void ly_log_dbg_groups(uint32_t dbg_groups);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200158
159#endif
160
161/**
Michal Vaskod8085612020-08-21 12:55:23 +0200162 * @brief Logger callback.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200163 *
164 * !IMPORTANT! If an error has a specific error-app-tag defined in the model, it will NOT be set
165 * at the time of calling this callback. It will be set right after, so to retrieve it
Radek Krejci8678fa42020-08-18 16:07:28 +0200166 * it must be checked afterwards with ::ly_errapptag().
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200167 *
Michal Vaskod8085612020-08-21 12:55:23 +0200168 * @param[in] level Log level of the message.
169 * @param[in] msg Message.
170 * @param[in] path Optional path of the concerned node.
171 */
172typedef void (*ly_log_clb)(LY_LOG_LEVEL level, const char *msg, const char *path);
173
174/**
175 * @brief Set logger callback.
176 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200177 * @param[in] clb Logging callback.
178 * @param[in] path flag to resolve and provide path as the third parameter of the callback function. In case of
179 * validation and some other errors, it can be useful to get the path to the problematic element. Note,
180 * that according to the tree type and the specific situation, the path can slightly differs (keys
181 * presence) or it can be NULL, so consider it as an optional parameter. If the flag is 0, libyang will
182 * not bother with resolving the path.
183 */
Radek Krejci857189e2020-09-01 13:26:36 +0200184void ly_set_log_clb(ly_log_clb clb, ly_bool path);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200185
186/**
187 * @brief Get logger callback.
188 * @return Logger callback (can be NULL).
189 */
Michal Vaskod8085612020-08-21 12:55:23 +0200190ly_log_clb ly_get_log_clb(void);
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200191
192/** @} log */
193
194/**
Radek Krejci8678fa42020-08-18 16:07:28 +0200195 * @page howtoErrors Errors Handling
196 *
197 * The most of the API functions directly returns error code in the form of ::LY_ERR value. In addition, if the ::LY_EVALID error
198 * arises, additional [validation error code](@ref ::LY_VECODE) is provided to categorize validation failures into several groups.
199 *
200 * All the errors arisen in connection with manipulation with the [context](@ref howtoContext), [YANG modules](@ref howtoSchema)
201 * or [YANG data](@ref howtoData), are recorded into the context and can be examined for the more detailed information. These
202 * records are stored as ::ly_err_item structures and they are not only context-specific, but also thread-specific.
203 *
204 * Storing error information is tightly connected with
205 * [logging](@ref howtoLogger). So the @ref logopts control if and which errors are stored in the context. By default, only the
206 * last error is recorded, so a new error replaces the previous one. This can be changed with ::LY_LOSTORE option set via
207 * ::ly_log_options(). Then, the errors are stored as a list preserving the previous error records. The stored records can be
208 * accessed using ::ly_err_last() or ::ly_err_first() functions. The ::ly_err_clean() is used to remove error records from the
209 * context.
210 *
211 * To print a specific error information via libyang logger, there is ::ly_err_print().
212 *
213 * To simplify access to the last error record in the context, there is a set of functions returning important error information.
214 * - ::ly_errapptag()
215 * - ::ly_errcode()
216 * - ::ly_vecode()
217 * - ::ly_errmsg()
218 * - ::ly_errpath()
219 *
220 * \note API for this group of functions is described in the [error information module](@ref errors).
221 */
222
223/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200224 * @defgroup errors Error information
Radek Krejci8678fa42020-08-18 16:07:28 +0200225 *
226 * Structures and functions to allow error information processing.
227 *
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200228 * @{
229 */
230
231/**
232 * @typedef LY_ERR
233 * @brief libyang's error codes returned by the libyang functions.
234 */
235typedef enum
236{
237 LY_SUCCESS = 0, /**< no error, not set by functions, included just to complete #LY_ERR enumeration */
238 LY_EMEM, /**< Memory allocation failure */
Radek Krejcidc1c7e72018-09-07 14:58:20 +0200239 LY_ESYS, /**< System call failure */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200240 LY_EINVAL, /**< Invalid value */
241 LY_EEXIST, /**< Item already exists */
Radek Krejcid33273d2018-10-25 14:55:52 +0200242 LY_ENOTFOUND, /**< Item does not exists */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200243 LY_EINT, /**< Internal error */
244 LY_EVALID, /**< Validation failure */
Radek Krejcid3ca0632019-04-16 16:54:54 +0200245 LY_EDENIED, /**< Operation is not allowed */
Radek Krejcie553e6d2019-06-07 15:33:18 +0200246 LY_EINCOMPLETE, /**< The operation did not failed, but for some reason it was not possible to finish it completely.
247 According to the specific use case, the caller is usually supposed to perform the operation again. */
Radek Krejci1f05b6a2019-07-18 16:15:06 +0200248 LY_ENOT, /**< Negative result */
Radek Krejcia4614e62020-05-15 14:19:28 +0200249 LY_EOTHER, /**< Unknown error */
250
251 LY_EPLUGIN = 128/**< Error reported by a plugin - the highest bit in the first byte is set.
252 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 +0200253} LY_ERR;
254
255/**
Radek Krejci8678fa42020-08-18 16:07:28 +0200256 * @ingroup logger
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200257 * @typedef LY_VECODE
258 * @brief libyang's codes of validation error. Whenever ly_errno is set to LY_EVALID, the ly_vecode is also set
259 * to the appropriate LY_VECODE value.
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200260 */
261typedef enum {
262 LYVE_SUCCESS = 0, /**< no error */
Radek Krejci94aa9942018-09-07 17:12:17 +0200263 LYVE_SYNTAX, /**< generic syntax error */
264 LYVE_SYNTAX_YANG, /**< YANG-related syntax error */
David Sedlák0a875b42019-03-07 22:24:05 +0100265 LYVE_SYNTAX_YIN, /**< YIN-related syntax error */
Radek Krejci70853c52018-10-15 14:46:16 +0200266 LYVE_REFERENCE, /**< invalid referencing or using an item */
Radek Krejcib1646a92018-11-02 16:08:26 +0100267 LYVE_XPATH, /**< invalid XPath expression */
Radek Krejcie7b95092019-05-15 11:03:07 +0200268 LYVE_SEMANTICS, /**< generic semantic error */
269 LYVE_SYNTAX_XML, /**< XML-related syntax error */
Radek Krejci1798aae2020-07-14 13:26:06 +0200270 LYVE_SYNTAX_JSON, /**< JSON-related syntax error */
Michal Vaskoecd62de2019-11-13 12:35:11 +0100271 LYVE_DATA, /**< YANG data does not reflect some of the module restrictions */
Radek Krejcia4614e62020-05-15 14:19:28 +0200272
273 LYVE_OTHER /**< Unknown error */
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200274} LY_VECODE;
275
276/**
277 * @brief Libyang full error structure.
278 */
279struct ly_err_item {
280 LY_LOG_LEVEL level;
281 LY_ERR no;
282 LY_VECODE vecode;
283 char *msg;
284 char *path;
285 char *apptag;
286 struct ly_err_item *next;
287 struct ly_err_item *prev; /* first item's prev points to the last item */
288};
289
290/**
291 * @brief Get the last (thread, context-specific) validation error code.
292 *
293 * This value is set only if ly_errno is #LY_EVALID.
294 *
295 * @param[in] ctx Relative context.
296 * @return Validation error code.
297 */
298LY_VECODE ly_vecode(const struct ly_ctx *ctx);
299
300/**
Radek Krejcid33273d2018-10-25 14:55:52 +0200301 * @brief Get the last (thread, context-specific) error code.
302 *
303 * @param[in] ctx Relative context.
304 * @return LY_ERR value of the last error code.
305 */
306LY_ERR ly_errcode(const struct ly_ctx *ctx);
307
308/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200309 * @brief Get the last (thread, context-specific) error message. If the coresponding module defined
310 * a specific error message, it will be used instead the default one.
311 *
312 * Sometimes, the error message is extended with path of the element where the problem is.
Radek Krejci8678fa42020-08-18 16:07:28 +0200313 * The path is available via ::ly_errpath().
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200314 *
315 * @param[in] ctx Relative context.
316 * @return Text of the last error message, empty string if there is no error.
317 */
318const char *ly_errmsg(const struct ly_ctx *ctx);
319
320/**
321 * @brief Get the last (thread, context-specific) path of the element where was an error.
322 *
Radek Krejci8678fa42020-08-18 16:07:28 +0200323 * The path always corresponds to the error message available via ::ly_errmsg(), so
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200324 * whenever a subsequent error message is printed, the path is erased or rewritten.
325 * The path reflects the type of the processed tree - data path for data tree functions
326 * and schema path in case of schema tree functions. In case of processing YIN schema
327 * or XML data, the path can be just XML path. In such a case, the corresponding
328 * ly_vecode (value 1-3) is set.
329 *
330 * @param[in] ctx Relative context.
331 * @return Path of the error element, empty string if error path does not apply to the last error.
332 */
333const char *ly_errpath(const struct ly_ctx *ctx);
334
335/**
336 * @brief Get the last (thread, context-specific) error-app-tag if there was a specific one defined
337 * in the module for the last error.
338 *
Radek Krejci8678fa42020-08-18 16:07:28 +0200339 * The app-tag always corresponds to the error message available via ::ly_errmsg(), so
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200340 * whenever a subsequent error message is printed, the app-tag is erased or rewritten.
341 *
342 * @param[in] ctx Relative context.
343 * @return Error-app-tag of the last error, empty string if the error-app-tag does not apply to the last error.
344 */
345const char *ly_errapptag(const struct ly_ctx *ctx);
346
347/**
348 * @brief Get the first (thread, context-specific) generated error structure.
349 *
350 * @param[in] ctx Relative context.
Radek Krejci572ee602020-09-16 14:35:08 +0200351 * @return The first error structure (can be NULL), do not modify!
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200352 */
353struct ly_err_item *ly_err_first(const struct ly_ctx *ctx);
354
355/**
Radek Krejci572ee602020-09-16 14:35:08 +0200356 * @brief Get the latest (thread, context-specific) generated error structure.
357 *
358 * @param[in] ctx Relative context.
359 * @return The last error structure (can be NULL), do not modify!
360 */
361struct ly_err_item *ly_err_last(const struct ly_ctx *ctx);
362
363/**
Radek Krejci5aeea3a2018-09-05 13:29:36 +0200364 * @brief Print the error structure as if just generated.
365 *
366 * @param[in] eitem Error item structure to print.
367 */
368void ly_err_print(struct ly_err_item *eitem);
369
370/**
371 * @brief Free error structures from a context.
372 *
373 * If \p eitem is not set, free all the error structures.
374 *
375 * @param[in] ctx Relative context.
376 * @param[in] eitem Oldest error structure to remove, optional.
377 */
378void ly_err_clean(struct ly_ctx *ctx, struct ly_err_item *eitem);
379
380/** @} errors */
381
382#ifdef __cplusplus
383}
384#endif
385
386#endif /* LY_LOG_H_ */