libyang REFACTOR simplify logging and extend location information

Simplify logger interface by using location information maintained in
the background. logger now prints all the available information: schema
path, data path and line numbers. However, the line number are quite
inaccurate (e.g. points to XML closing parent element) and some future
tuning would be great.
diff --git a/src/common.h b/src/common.h
index 7eb5d64..d7324f9 100644
--- a/src/common.h
+++ b/src/common.h
@@ -58,15 +58,6 @@
  * Logger
  *****************************************************************************/
 
-enum LY_VLOG_ELEM {
-    LY_VLOG_NONE = 0,
-    LY_VLOG_LINE, /* line number (uint64_t*) */
-    LY_VLOG_LYSC, /* struct lysc_node* */
-    LY_VLOG_LYD,  /* struct lyd_node* */
-    LY_VLOG_STR,  /* const char* */
-    LY_VLOG_PREV  /* use exact same previous path */
-};
-
 extern THREAD_LOCAL enum int_log_opts log_opt;
 extern volatile LY_LOG_LEVEL ly_ll;
 extern volatile uint32_t ly_log_opts;
@@ -98,12 +89,10 @@
  * @brief Print Validation error and store it into the context (if provided).
  *
  * @param[in] ctx libyang context to store the error record. If not provided, the error is just printed.
- * @param[in] elem_type Type of the data in @p elem variable.
- * @param[in] elem Object to provide more information about the place where the error appeared.
  * @param[in] code Validation error code.
  * @param[in] format Format string to print.
  */
-void ly_vlog(const struct ly_ctx *ctx, enum LY_VLOG_ELEM elem_type, const void *elem, LY_VECODE code, const char *format, ...);
+void ly_vlog(const struct ly_ctx *ctx, LY_VECODE code, const char *format, ...);
 
 /**
  * @brief Logger's location data setter.
@@ -178,7 +167,10 @@
 #define LOGMEM(CTX) LOGERR(CTX, LY_EMEM, "Memory allocation failed (%s()).", __func__)
 #define LOGINT(CTX) LOGERR(CTX, LY_EINT, "Internal error (%s:%d).", __FILE__, __LINE__)
 #define LOGARG(CTX, ARG) LOGERR(CTX, LY_EINVAL, "Invalid argument %s (%s()).", #ARG, __func__)
-#define LOGVAL(CTX, ELEM_TYPE, ELEM, CODE, ...) ly_vlog(CTX, ELEM_TYPE, ELEM, CODE, ##__VA_ARGS__)
+#define LOGVAL(CTX, CODE, ...) ly_vlog(CTX, CODE, ##__VA_ARGS__)
+#define LOGVAL_LINE(CTX, LINE, CODE, ...) \
+    ly_log_location(CTX, NULL, NULL, NULL, NULL, LINE, 0); \
+    ly_vlog(CTX, CODE, ##__VA_ARGS__)
 
 #define LOGMEM_RET(CTX) LOGMEM(CTX); return LY_EMEM
 #define LOGINT_RET(CTX) LOGINT(CTX); return LY_EINT
@@ -225,8 +217,6 @@
 #define LY_VCODE_TRAILING_SUBMOD LYVE_SYNTAX, "Trailing garbage \"%.*s%s\" after submodule, expected end-of-input."
 
 #define LY_VCODE_INVAL_MINMAX   LYVE_SEMANTICS, "Invalid combination of min-elements and max-elements: min value %u is bigger than the max value %u."
-#define LY_VCODE_CIRC_WHEN      LYVE_SEMANTICS, "When condition of \"%s\" includes a self-reference (referenced by when of \"%s\")."
-#define LY_VCODE_DUMMY_WHEN     LYVE_SEMANTICS, "When condition of \"%s\" is accessing its own conditional node."
 #define LY_VCODE_NAME_COL       LYVE_SEMANTICS, "Name collision between %s of name \"%s\"."
 #define LY_VCODE_NAME2_COL      LYVE_SEMANTICS, "Name collision between %s and %s of name \"%s\"."
 
diff --git a/src/in.c b/src/in.c
index 8e8cf07..46673e9 100644
--- a/src/in.c
+++ b/src/in.c
@@ -395,42 +395,48 @@
 LY_ERR
 lyd_parser_check_schema(struct lyd_ctx *lydctx, const struct lysc_node *snode)
 {
-    /* alternatively, we could provide line for the error messages, but it doesn't work for the LYB format */
+    LY_ERR ret = LY_EVALID;
+
+    LOG_LOCSET(lydctx->data_ctx->ctx, snode, NULL, NULL, NULL);
 
     if ((lydctx->parse_options & LYD_PARSE_NO_STATE) && (snode->flags & LYS_CONFIG_R)) {
-        LOGVAL(lydctx->data_ctx->ctx, LY_VLOG_LYSC, snode, LY_VCODE_INNODE, "state", snode->name);
-        return LY_EVALID;
+        LOGVAL(lydctx->data_ctx->ctx, LY_VCODE_INNODE, "state", snode->name);
+        goto cleanup;
     }
 
     if (snode->nodetype & (LYS_RPC | LYS_ACTION)) {
         if (lydctx->int_opts & (LYD_INTOPT_RPC | LYD_INTOPT_REPLY)) {
             if (lydctx->op_node) {
-                LOGVAL(lydctx->data_ctx->ctx, LY_VLOG_LYSC, snode, LYVE_DATA, "Unexpected %s element \"%s\", %s \"%s\" already parsed.",
+                LOGVAL(lydctx->data_ctx->ctx, LYVE_DATA, "Unexpected %s element \"%s\", %s \"%s\" already parsed.",
                         lys_nodetype2str(snode->nodetype), snode->name,
                         lys_nodetype2str(lydctx->op_node->schema->nodetype), lydctx->op_node->schema->name);
-                return LY_EVALID;
+                goto cleanup;
             }
         } else {
-            LOGVAL(lydctx->data_ctx->ctx, LY_VLOG_LYSC, snode, LYVE_DATA, "Unexpected %s element \"%s\".",
+            LOGVAL(lydctx->data_ctx->ctx, LYVE_DATA, "Unexpected %s element \"%s\".",
                     lys_nodetype2str(snode->nodetype), snode->name);
-            return LY_EVALID;
+            goto cleanup;
         }
     } else if (snode->nodetype == LYS_NOTIF) {
         if (lydctx->int_opts & LYD_INTOPT_NOTIF) {
             if (lydctx->op_node) {
-                LOGVAL(lydctx->data_ctx->ctx, LY_VLOG_LYSC, snode, LYVE_DATA, "Unexpected %s element \"%s\", %s \"%s\" already parsed.",
+                LOGVAL(lydctx->data_ctx->ctx, LYVE_DATA, "Unexpected %s element \"%s\", %s \"%s\" already parsed.",
                         lys_nodetype2str(snode->nodetype), snode->name,
                         lys_nodetype2str(lydctx->op_node->schema->nodetype), lydctx->op_node->schema->name);
-                return LY_EVALID;
+                goto cleanup;
             }
         } else {
-            LOGVAL(lydctx->data_ctx->ctx, LY_VLOG_LYSC, snode, LYVE_DATA, "Unexpected %s element \"%s\".",
+            LOGVAL(lydctx->data_ctx->ctx, LYVE_DATA, "Unexpected %s element \"%s\".",
                     lys_nodetype2str(snode->nodetype), snode->name);
-            return LY_EVALID;
+            goto cleanup;
         }
     }
 
-    return LY_SUCCESS;
+    ret = LY_SUCCESS;
+
+cleanup:
+    LOG_LOCBACK(lydctx->data_ctx->ctx, 1, 0, 0, 0);
+    return ret;
 }
 
 LY_ERR
diff --git a/src/json.c b/src/json.c
index 059cf88..eca191e 100644
--- a/src/json.c
+++ b/src/json.c
@@ -115,8 +115,8 @@
             return LY_SUCCESS;
         }
     } else {
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
-                "Unexpected character \"%c\" after JSON %s.", *jsonctx->in->current, lyjson_token2str(lyjson_ctx_status(jsonctx, 0)));
+        LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Unexpected character \"%c\" after JSON %s.",
+                *jsonctx->in->current, lyjson_token2str(lyjson_ctx_status(jsonctx, 0)));
     }
 
     return LY_EVALID;
@@ -217,8 +217,7 @@
                 offset++;
                 for (value = i = 0; i < 4; i++) {
                     if (!in[offset + i]) {
-                        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
-                                "Invalid basic multilingual plane character \"%s\".", &in[slash]);
+                        LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Invalid basic multilingual plane character \"%s\".", &in[slash]);
                         goto error;
                     } else if (isdigit(in[offset + i])) {
                         u = (in[offset + i] - '0');
@@ -232,16 +231,15 @@
                 break;
             default:
                 /* invalid escape sequence */
-                LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
-                        "Invalid character escape sequence \\%c.", in[offset]);
+                LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Invalid character escape sequence \\%c.", in[offset]);
                 goto error;
 
             }
 
             offset += i;   /* add read escaped characters */
             LY_CHECK_ERR_GOTO(ly_pututf8(&buf[len], value, &u),
-                    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
-                    "Invalid character reference \"%.*s\" (0x%08x).", offset - slash, &in[slash], value),
+                    LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Invalid character reference \"%.*s\" (0x%08x).",
+                    offset - slash, &in[slash], value),
                     error);
             len += u;      /* update number of bytes in buffer */
             in += offset;  /* move the input by the processed bytes stored in the buffer ... */
@@ -270,11 +268,11 @@
             size_t code_len = 0;
 
             LY_CHECK_ERR_GOTO(ly_getutf8(&c, &code, &code_len),
-                    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INCHAR, in[offset]), error);
+                    LOGVAL(jsonctx->ctx, LY_VCODE_INCHAR, in[offset]), error);
 
             LY_CHECK_ERR_GOTO(!is_jsonstrchar(code),
-                    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
-                    "Invalid character in JSON string \"%.*s\" (0x%08x).", &in[offset] - start + code_len, start, code),
+                    LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Invalid character in JSON string \"%.*s\" (0x%08x).",
+                    &in[offset] - start + code_len, start, code),
                     error);
 
             /* character is ok, continue */
@@ -283,8 +281,8 @@
     }
 
     /* EOF reached before endchar */
-    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_EOF);
-    LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &start_line, LYVE_SYNTAX, "Missing quotation-mark at the end of a JSON string.");
+    LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
+    LOGVAL_LINE(jsonctx->ctx, start_line, LYVE_SYNTAX, "Missing quotation-mark at the end of a JSON string.");
 
 error:
     free(buf);
@@ -341,9 +339,9 @@
     } else {
 invalid_character:
         if (in[offset]) {
-            LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX, "Invalid character in JSON Number value (\"%c\").", in[offset]);
+            LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Invalid character in JSON Number value (\"%c\").", in[offset]);
         } else {
-            LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_EOF);
+            LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
         }
         return LY_EVALID;
     }
@@ -382,8 +380,8 @@
         errno = 0;
         e_val = strtol(e_ptr, &ptr, LY_BASE_DEC);
         if (errno) {
-            LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SEMANTICS,
-                    "Exponent out-of-bounds in a JSON Number value (%.*s).", offset - minus - (e_ptr - in), e_ptr);
+            LOGVAL(jsonctx->ctx, LYVE_SEMANTICS, "Exponent out-of-bounds in a JSON Number value (%.*s).",
+                    offset - minus - (e_ptr - in), e_ptr);
             return LY_EVALID;
         }
 
@@ -484,7 +482,7 @@
 lyjson_object_name(struct lyjson_ctx *jsonctx)
 {
     if (*jsonctx->in->current != '"') {
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
+        LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                 jsonctx->in->current, "a JSON object's member");
         return LY_EVALID;
     }
@@ -493,8 +491,8 @@
     LY_CHECK_RET(lyjson_string_(jsonctx));
     LY_CHECK_RET(skip_ws(jsonctx));
     if (*jsonctx->in->current != ':') {
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INSTREXP,
-                LY_VCODE_INSTREXP_len(jsonctx->in->current), jsonctx->in->current, "a JSON object's name-separator ':'");
+        LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current), jsonctx->in->current,
+                "a JSON object's name-separator ':'");
         return LY_EVALID;
     }
     ly_in_skip(jsonctx->in, 1);
@@ -600,7 +598,7 @@
 
     } else {
         /* unexpected value */
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
+        LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
                 jsonctx->in->current, "a JSON value");
         return LY_EVALID;
     }
@@ -624,6 +622,8 @@
     jsonctx->ctx = ctx;
     jsonctx->in = in;
 
+    LOG_LOCINIT(ctx, NULL, NULL, NULL, in);
+
     /* parse JSON value, if any */
     LY_CHECK_GOTO(ret = skip_ws(jsonctx), cleanup);
     if (lyjson_ctx_status(jsonctx, 0) == LYJSON_END) {
@@ -634,7 +634,7 @@
     ret = lyjson_value(jsonctx);
 
     if ((jsonctx->status.count > 1) && (lyjson_ctx_status(jsonctx, 0) == LYJSON_END)) {
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_EOF);
+        LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
         ret = LY_EVALID;
     }
 
@@ -705,8 +705,7 @@
     LY_CHECK_RET(skip_ws(jsonctx));
     if (toplevel && !jsonctx->status.count) {
         /* EOF expected, but there are some data after the top level token */
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
-                "Expecting end-of-input, but some data follows the top level JSON value.");
+        LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Expecting end-of-input, but some data follows the top level JSON value.");
         return LY_EVALID;
     }
 
@@ -736,14 +735,14 @@
         JSON_PUSH_STATUS_RET(jsonctx, prev + 1);
     } else {
         /* unexpected value */
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
-                jsonctx->in->current, prev == LYJSON_ARRAY ? "another JSON value in array" : "another JSON object's member");
+        LOGVAL(jsonctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current), jsonctx->in->current,
+                prev == LYJSON_ARRAY ? "another JSON value in array" : "another JSON object's member");
         return LY_EVALID;
     }
 
 result:
     if ((ret == LY_SUCCESS) && (jsonctx->status.count > 1) && (lyjson_ctx_status(jsonctx, 0) == LYJSON_END)) {
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_EOF);
+        LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
         ret = LY_EVALID;
     }
 
@@ -775,6 +774,8 @@
         return;
     }
 
+    LOG_LOCBACK(jsonctx->ctx, 0, 0, 0, 1);
+
     if (jsonctx->dynamic) {
         free((char *)jsonctx->value);
     }
diff --git a/src/log.c b/src/log.c
index 640c8ff..7498c74 100644
--- a/src/log.c
+++ b/src/log.c
@@ -499,57 +499,73 @@
 }
 
 static LY_ERR
-ly_vlog_build_path(const struct ly_ctx *ctx, enum LY_VLOG_ELEM elem_type, const void *elem, char **path)
+ly_vlog_build_path(const struct ly_ctx *ctx, struct ly_log_location_s *location, char **path)
 {
     int rc;
+    char *str = NULL, *prev = NULL;
+    *path = NULL;
 
-    switch (elem_type) {
-    case LY_VLOG_STR:
-        *path = strdup(elem);
+    if (location->paths.count && ((const char *)(location->paths.objs[location->paths.count - 1]))[0]) {
+        /* simply get what is in the provided path string */
+        *path = strdup((const char *)location->paths.objs[location->paths.count - 1]);
         LY_CHECK_ERR_RET(!(*path), LOGMEM(ctx), LY_EMEM);
-        break;
-    case LY_VLOG_LINE:
-        rc = asprintf(path, "Line number %" PRIu64 ".", *((uint64_t *)elem));
-        LY_CHECK_ERR_RET(rc == -1, LOGMEM(ctx), LY_EMEM);
-        break;
-    case LY_VLOG_LYSC:
-        *path = lysc_path(elem, LYSC_PATH_LOG, NULL, 0);
-        LY_CHECK_ERR_RET(!(*path), LOGMEM(ctx), LY_EMEM);
-        break;
-    case LY_VLOG_LYD:
-        *path = lyd_path(elem, LYD_PATH_STD, NULL, 0);
-        LY_CHECK_ERR_RET(!(*path), LOGMEM(ctx), LY_EMEM);
-        break;
-    default:
-        /* shouldn't be here */
-        LOGINT_RET(ctx);
+    } else {
+        /* generate location string */
+        if (location->scnodes.count) {
+            str = lysc_path(location->scnodes.objs[location->scnodes.count - 1], LYSC_PATH_LOG, NULL, 0);
+            LY_CHECK_ERR_RET(!str, LOGMEM(ctx), LY_EMEM);
+
+            rc = asprintf(path, "Schema location %s", str);
+            free(str);
+            LY_CHECK_ERR_RET(rc == -1, LOGMEM(ctx), LY_EMEM);
+        }
+        if (location->dnodes.count) {
+            prev = *path;
+            str = lyd_path(location->dnodes.objs[location->dnodes.count - 1], LYD_PATH_STD, NULL, 0);
+            LY_CHECK_ERR_RET(!str, LOGMEM(ctx), LY_EMEM);
+
+            rc = asprintf(path, "%s%sata location %s", prev ? prev : "", prev ? ", d" : "D", str);
+            free(str);
+            free(prev);
+            LY_CHECK_ERR_RET(rc == -1, LOGMEM(ctx), LY_EMEM);
+        }
+        if (location->line) {
+            prev = *path;
+            rc = asprintf(path, "%s%sine number %" PRIu64, prev ? prev : "", prev ? ", l" : "L", location->line);
+            free(prev);
+            LY_CHECK_ERR_RET(rc == -1, LOGMEM(ctx), LY_EMEM);
+
+            location->line = 0;
+        } else if (location->inputs.count) {
+            prev = *path;
+            rc = asprintf(path, "%s%sine number %" PRIu64, prev ? prev : "", prev ? ", l" : "L",
+                    ((struct ly_in *)location->inputs.objs[location->inputs.count - 1])->line);
+            free(prev);
+            LY_CHECK_ERR_RET(rc == -1, LOGMEM(ctx), LY_EMEM);
+        }
+
+        if (*path) {
+            prev = *path;
+            rc = asprintf(path, "%s.", prev);
+            free(prev);
+            LY_CHECK_ERR_RET(rc == -1, LOGMEM(ctx), LY_EMEM);
+        }
     }
 
     return LY_SUCCESS;
 }
 
 void
-ly_vlog(const struct ly_ctx *ctx, enum LY_VLOG_ELEM elem_type, const void *elem, LY_VECODE code, const char *format, ...)
+ly_vlog(const struct ly_ctx *ctx, LY_VECODE code, const char *format, ...)
 {
     va_list ap;
     char *path = NULL;
-    const struct ly_err_item *first;
 
-    if (path_flag && (elem_type != LY_VLOG_NONE)) {
-        if (elem_type == LY_VLOG_PREV) {
-            /* use previous path */
-            first = ly_err_first(ctx);
-            if (first && first->prev->path) {
-                path = strdup(first->prev->path);
-            }
-        } else {
-            /* print path */
-            if (!elem) {
-                /* top-level */
-                path = strdup("/");
-            } else {
-                ly_vlog_build_path(ctx, elem_type, elem, &path);
-            }
+    if (path_flag && ctx) {
+        /* get the location information */
+        struct ly_log_location_s *location = pthread_getspecific(ctx->log_location_key);
+        if (location) {
+            ly_vlog_build_path(ctx, location, &path);
         }
     }
 
diff --git a/src/parser_json.c b/src/parser_json.c
index da65f2f..6348459 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -191,12 +191,15 @@
 lydjson_get_snode(const struct lyd_json_ctx *lydctx, ly_bool is_attr, const char *prefix, size_t prefix_len, const char *name,
         size_t name_len, const struct lyd_node_inner *parent, const struct lysc_node **snode_p)
 {
+    LY_ERR ret = LY_SUCCESS;
     struct lys_module *mod = NULL;
     uint32_t getnext_opts = lydctx->int_opts & LYD_INTOPT_REPLY ? LYS_GETNEXT_OUTPUT : 0;
 
     /* init return value */
     *snode_p = NULL;
 
+    LOG_LOCSET(lydctx->jsonctx->ctx, NULL, (const struct lyd_node *)parent, NULL, NULL);
+
     /* get the element module */
     if (prefix_len) {
         mod = ly_ctx_get_module_implemented2(lydctx->jsonctx->ctx, prefix, prefix_len);
@@ -205,17 +208,20 @@
             mod = parent->schema->module;
         }
     } else {
-        LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, parent, LYVE_SYNTAX_JSON, "Top-level JSON object member \"%.*s\" must be namespace-qualified.",
+        LOGVAL(lydctx->jsonctx->ctx, LYVE_SYNTAX_JSON, "Top-level JSON object member \"%.*s\" must be namespace-qualified.",
                 is_attr ? name_len + 1 : name_len, is_attr ? name - 1 : name);
-        return LY_EVALID;
+        ret = LY_EVALID;
+        goto cleanup;
     }
     if (!mod) {
         if (lydctx->parse_options & LYD_PARSE_STRICT) {
-            LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, parent, LYVE_REFERENCE, "No module named \"%.*s\" in the context.", prefix_len, prefix);
-            return LY_EVALID;
+            LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "No module named \"%.*s\" in the context.", prefix_len, prefix);
+            ret = LY_EVALID;
+            goto cleanup;
         }
         if (!(lydctx->parse_options & LYD_PARSE_OPAQ)) {
-            return LY_ENOT;
+            ret = LY_ENOT;
+            goto cleanup;
         }
     }
 
@@ -224,20 +230,24 @@
         *snode_p = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
         if (!*snode_p) {
             if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, parent, LYVE_REFERENCE, "Node \"%.*s\" not found in the \"%s\" module.",
+                LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Node \"%.*s\" not found in the \"%s\" module.",
                         name_len, name, mod->name);
-                return LY_EVALID;
+                ret = LY_EVALID;
+                goto cleanup;
             } else if (!(lydctx->parse_options & LYD_PARSE_OPAQ)) {
                 /* skip element with children */
-                return LY_ENOT;
+                ret = LY_ENOT;
+                goto cleanup;
             }
         } else {
             /* check that schema node is valid and can be used */
-            LY_CHECK_RET(lyd_parser_check_schema((struct lyd_ctx *)lydctx, *snode_p));
+            ret = lyd_parser_check_schema((struct lyd_ctx *)lydctx, *snode_p);
         }
     }
 
-    return LY_SUCCESS;
+cleanup:
+    LOG_LOCBACK(lydctx->jsonctx->ctx, 0, parent ? 1 : 0, 0, 0);
+    return ret;
 }
 
 /**
@@ -482,6 +492,7 @@
     struct lyd_node *node, *attr, *next, *start = *first_p, *meta_iter;
     uint64_t instance = 0;
     const char *prev = NULL;
+    uint32_t log_location_items = 0;
 
     /* finish linking metadata */
     LY_LIST_FOR_SAFE(*first_p, next, attr) {
@@ -497,6 +508,9 @@
             continue;
         }
 
+        LOG_LOCSET(lydctx->jsonctx->ctx, NULL, attr, NULL, NULL);
+        log_location_items++;
+
         if (prev != meta_container->name.name) {
             /* metas' names are stored in dictionary, so checking pointers must works */
             lydict_remove(lydctx->jsonctx->ctx, prev);
@@ -515,8 +529,8 @@
                 }
 
                 if (((struct lyd_node_opaq *)node)->hints & LYD_NODEHINT_LIST) {
-                    LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, node, LYVE_SYNTAX,
-                            "Metadata container references a sibling list node %s.", ((struct lyd_node_opaq *)node)->name.name);
+                    LOGVAL(lydctx->jsonctx->ctx, LYVE_SYNTAX, "Metadata container references a sibling list node %s.",
+                            ((struct lyd_node_opaq *)node)->name.name);
                     ret = LY_EVALID;
                     goto cleanup;
                 }
@@ -572,7 +586,7 @@
                                 &dynamic, LY_PREF_JSON, NULL, meta->hints);
                         LY_CHECK_GOTO(ret, cleanup);
                     } else if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                        LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, node, LYVE_REFERENCE,
+                        LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE,
                                 "Unknown (or not implemented) YANG module \"%s\" for metadata \"%s%s%s\".",
                                 meta->name.prefix, meta->name.prefix, ly_strlen(meta->name.prefix) ? ":" : "", meta->name.name);
                         ret = LY_EVALID;
@@ -590,12 +604,11 @@
         if (match != instance) {
             /* there is no corresponding data node for the metadata */
             if (instance > 1) {
-                LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, *first_p ? (*first_p)->parent : NULL, LYVE_REFERENCE,
-                        "Missing %d%s JSON data instance to be coupled with %s metadata.", instance,
-                        instance == 2 ? "nd" : (instance == 3 ? "rd" : "th"), meta_container->name.name);
+                LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Missing %d%s JSON data instance to be coupled with %s metadata.",
+                        instance, instance == 2 ? "nd" : (instance == 3 ? "rd" : "th"), meta_container->name.name);
             } else {
-                LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, *first_p ? (*first_p)->parent : NULL, LYVE_REFERENCE,
-                        "Missing JSON data instance to be coupled with %s metadata.", meta_container->name.name);
+                LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Missing JSON data instance to be coupled with %s metadata.",
+                        meta_container->name.name);
             }
             ret = LY_EVALID;
         } else {
@@ -605,11 +618,15 @@
             }
             lyd_free_tree(attr);
         }
+
+        LOG_LOCBACK(lydctx->jsonctx->ctx, 0, log_location_items, 0, 0);
+        log_location_items = 0;
     }
 
 cleanup:
     lydict_remove(lydctx->jsonctx->ctx, prev);
 
+    LOG_LOCBACK(lydctx->jsonctx->ctx, 0, log_location_items, 0, 0);
     return ret;
 }
 
@@ -671,8 +688,7 @@
         LY_CHECK_GOTO(status != LYJSON_OBJECT && status != LYJSON_NULL, representation_error);
 
         if (!node || (node->schema != prev->schema)) {
-            LOGVAL(lydctx->jsonctx->ctx, LY_VLOG_LYD, prev->parent, LYVE_REFERENCE,
-                    "Missing JSON data instance no. %u of %s:%s to be coupled with metadata.",
+            LOGVAL(lydctx->jsonctx->ctx, LYVE_REFERENCE, "Missing JSON data instance no. %u of %s:%s to be coupled with metadata.",
                     instance, prev->schema->module->name, prev->schema->name);
             ret = LY_EVALID;
             goto cleanup;
@@ -708,17 +724,17 @@
     /* process all the members inside a single metadata object */
     assert(status == LYJSON_OBJECT);
 
+    LOG_LOCSET(ctx, snode, NULL, NULL, NULL);
+
     while (status != LYJSON_OBJECT_CLOSED) {
         lydjson_parse_name(lydctx->jsonctx->value, lydctx->jsonctx->value_len, &name, &name_len, &prefix, &prefix_len, &is_attr);
         if (!prefix) {
-            LOGVAL(ctx, LY_VLOG_LYD, (void *)node, LYVE_SYNTAX_JSON,
-                    "Metadata in JSON must be namespace-qualified, missing prefix for \"%.*s\".",
+            LOGVAL(ctx, LYVE_SYNTAX_JSON, "Metadata in JSON must be namespace-qualified, missing prefix for \"%.*s\".",
                     lydctx->jsonctx->value_len, lydctx->jsonctx->value);
             ret = LY_EVALID;
             goto cleanup;
         } else if (is_attr) {
-            LOGVAL(ctx, LY_VLOG_LYD, (void *)node, LYVE_SYNTAX_JSON,
-                    "Invalid format of the Metadata identifier in JSON, unexpected '@' in \"%.*s\"",
+            LOGVAL(ctx, LYVE_SYNTAX_JSON, "Invalid format of the Metadata identifier in JSON, unexpected '@' in \"%.*s\"",
                     lydctx->jsonctx->value_len, lydctx->jsonctx->value);
             ret = LY_EVALID;
             goto cleanup;
@@ -728,8 +744,7 @@
         mod = ly_ctx_get_module_implemented2(ctx, prefix, prefix_len);
         if (!mod) {
             if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                LOGVAL(ctx, LY_VLOG_LYD, (void *)node, LYVE_REFERENCE,
-                        "Prefix \"%.*s\" of the metadata \"%.*s\" does not match any module in the context.",
+                LOGVAL(ctx, LYVE_REFERENCE, "Prefix \"%.*s\" of the metadata \"%.*s\" does not match any module in the context.",
                         prefix_len, prefix, name_len, name);
                 ret = LY_EVALID;
                 goto cleanup;
@@ -789,15 +804,17 @@
     LY_CHECK_GOTO(ret, cleanup);
 
 cleanup:
+    LOG_LOCBACK(ctx, 1, 0, 0, 0);
     return ret;
 
 representation_error:
-    LOGVAL(ctx, LY_VLOG_LYD, (void *)node, LYVE_SYNTAX_JSON,
+    LOGVAL(ctx, LYVE_SYNTAX_JSON,
             "The attribute(s) of %s \"%s\" is expected to be represented as JSON %s, but input data contains @%s/%s.",
             lys_nodetype2str(nodetype), node->schema ? node->schema->name : ((struct lyd_node_opaq *)node)->name.name,
             expected, lyjson_token2str(status), in_parent ? "" : "name");
 
-    return LY_EVALID;
+    ret = LY_EVALID;
+    goto cleanup;
 }
 
 /**
@@ -1033,35 +1050,39 @@
             ret = lyd_create_inner(snode, node);
             LY_CHECK_RET(ret);
 
+            LOG_LOCSET(lydctx->jsonctx->ctx, snode, *node, NULL, NULL);
+
             /* process children */
             while (*status != LYJSON_OBJECT_CLOSED && *status != LYJSON_OBJECT_EMPTY) {
                 ret = lydjson_subtree_r(lydctx, (struct lyd_node_inner *)*node, lyd_node_children_p(*node));
-                LY_CHECK_RET(ret);
+                LY_CHECK_ERR_RET(ret, LOG_LOCBACK(lydctx->jsonctx->ctx, 1, 1, 0, 0), ret);
                 *status = lyjson_ctx_status(lydctx->jsonctx, 0);
             }
 
             /* finish linking metadata */
             ret = lydjson_metadata_finish(lydctx, lyd_node_children_p(*node));
-            LY_CHECK_RET(ret);
+            LY_CHECK_ERR_RET(ret, LOG_LOCBACK(lydctx->jsonctx->ctx, 1, 1, 0, 0), ret);
 
             if (snode->nodetype == LYS_LIST) {
                 /* check all keys exist */
                 ret = lyd_parse_check_keys(*node);
-                LY_CHECK_RET(ret);
+                LY_CHECK_ERR_RET(ret, LOG_LOCBACK(lydctx->jsonctx->ctx, 1, 1, 0, 0), ret);
             }
 
             if (!(lydctx->parse_options & LYD_PARSE_ONLY)) {
                 /* new node validation, autodelete CANNOT occur, all nodes are new */
                 ret = lyd_validate_new(lyd_node_children_p(*node), snode, NULL, NULL);
-                LY_CHECK_RET(ret);
+                LY_CHECK_ERR_RET(ret, LOG_LOCBACK(lydctx->jsonctx->ctx, 1, 1, 0, 0), ret);
 
                 /* add any missing default children */
                 ret = lyd_new_implicit_r(*node, lyd_node_children_p(*node), NULL, NULL, &lydctx->node_types,
                         &lydctx->node_when, (lydctx->validate_options & LYD_VALIDATE_NO_STATE) ?
                         LYD_IMPLICIT_NO_STATE : 0, NULL);
-                LY_CHECK_RET(ret);
+                LY_CHECK_ERR_RET(ret, LOG_LOCBACK(lydctx->jsonctx->ctx, 1, 1, 0, 0), ret);
             }
 
+            LOG_LOCBACK(lydctx->jsonctx->ctx, 1, 1, 0, 0);
+
             /* move JSON parser */
             ret = lyjson_ctx_next(lydctx->jsonctx, status);
             LY_CHECK_RET(ret);
@@ -1160,7 +1181,7 @@
         if (!name_len && !prefix_len) {
             /* parent's metadata without a name - use the schema from the parent */
             if (!parent) {
-                LOGVAL(ctx, LY_VLOG_LYD, NULL, LYVE_SYNTAX_JSON,
+                LOGVAL(ctx, LYVE_SYNTAX_JSON,
                         "Invalid metadata format - \"@\" can be used only inside anydata, container or list entries.");
                 ret = LY_EVALID;
                 goto cleanup;
@@ -1274,10 +1295,10 @@
     return ret;
 
 representation_error:
-    LOGVAL(ctx, LY_VLOG_LYD, parent, LYVE_SYNTAX_JSON,
-            "The %s \"%s\" is expected to be represented as JSON %s, but input data contains name/%s.",
+    LOG_LOCSET(ctx, NULL, (const struct lyd_node *)parent, NULL, NULL);
+    LOGVAL(ctx, LYVE_SYNTAX_JSON, "The %s \"%s\" is expected to be represented as JSON %s, but input data contains name/%s.",
             lys_nodetype2str(snode->nodetype), snode->name, expected, lyjson_token2str(status));
-
+    LOG_LOCBACK(ctx, 0, parent ? 1 : 0, 0, 0);
     ret = LY_EVALID;
     goto cleanup;
 }
@@ -1326,7 +1347,7 @@
         return LY_SUCCESS;
     } else {
         /* expecting top-level object */
-        LOGVAL(ctx, LY_VLOG_LINE, &in->line, LYVE_SYNTAX_JSON, "Expected top-level JSON object, but %s found.",
+        LOGVAL(ctx, LYVE_SYNTAX_JSON, "Expected top-level JSON object, but %s found.",
                 lyjson_token2str(*status));
         *lydctx_p = NULL;
         lyd_json_ctx_free((struct lyd_ctx *)lydctx);
@@ -1498,11 +1519,11 @@
 
     /* make sure we have parsed some notification */
     if (!lydctx->op_node) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_DATA, "Missing the \"notification\" node.");
+        LOGVAL(ctx, LYVE_DATA, "Missing the \"notification\" node.");
         ret = LY_EVALID;
         goto cleanup;
     } else if (lydctx->jsonctx->in->current[0] && (lyjson_ctx_status(lydctx->jsonctx, 0) != LYJSON_OBJECT_CLOSED)) {
-        LOGVAL(ctx, LY_VLOG_LINE, &lydctx->jsonctx->in->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
+        LOGVAL(ctx, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
                 tree->schema->name);
         ret = LY_EVALID;
         goto cleanup;
@@ -1582,10 +1603,10 @@
 {
     LY_CHECK_RET(lyjson_ctx_next(jsonctx, status));
     if (*status == LYJSON_END) {
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
+        LOGVAL(jsonctx->ctx, LY_VCODE_EOF);
         return LY_EVALID;
     } else if (*status != LYJSON_OBJECT_CLOSED) {
-        LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX, "Unexpected sibling member \"%.*s\" of \"%s\".",
+        LOGVAL(jsonctx->ctx, LYVE_SYNTAX, "Unexpected sibling member \"%.*s\" of \"%s\".",
                 jsonctx->value_len, jsonctx->value, object_id);
         return LY_EVALID;
     }
@@ -1642,11 +1663,11 @@
 
     /* make sure we have parsed some operation */
     if (!lydctx->op_node) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_DATA, "Missing the rpc/action node.");
+        LOGVAL(ctx, LYVE_DATA, "Missing the rpc/action node.");
         ret = LY_EVALID;
         goto cleanup;
     } else if (lydctx->jsonctx->in->current[0] && (lyjson_ctx_status(lydctx->jsonctx, 0) != LYJSON_OBJECT_CLOSED)) {
-        LOGVAL(ctx, LY_VLOG_LINE, &lydctx->jsonctx->in->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
+        LOGVAL(ctx, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
                 tree->schema->name);
         ret = LY_EVALID;
         goto cleanup;
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index c7a64b3..7fc3ea1 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -652,10 +652,10 @@
 
     if (!sibling && (lybctx->parse_options & LYD_PARSE_STRICT)) {
         if (mod) {
-            LOGVAL(lybctx->lybctx->ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Failed to find matching hash for a top-level node"
+            LOGVAL(lybctx->lybctx->ctx, LYVE_REFERENCE, "Failed to find matching hash for a top-level node"
                     " from \"%s\".", mod->name);
         } else {
-            LOGVAL(lybctx->lybctx->ctx, LY_VLOG_LYSC, sparent, LYVE_REFERENCE, "Failed to find matching hash for a child node"
+            LOGVAL(lybctx->lybctx->ctx, LYVE_REFERENCE, "Failed to find matching hash for a child node"
                     " of \"%s\".", sparent->name);
         }
         return LY_EVALID;
@@ -1050,7 +1050,7 @@
     if (data_type == (LYD_INTOPT_RPC | LYD_INTOPT_REPLY)) {
         /* make sure we have parsed some operation */
         if (!lybctx->op_node) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_DATA, "Missing the \"rpc\"/\"action\" node.");
+            LOGVAL(ctx, LYVE_DATA, "Missing the \"rpc\"/\"action\" node.");
             ret = LY_EVALID;
             goto cleanup;
         }
@@ -1063,7 +1063,7 @@
     } else if (data_type == LYD_INTOPT_NOTIF) {
         /* make sure we have parsed some notification */
         if (!lybctx->op_node) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_DATA, "Missing the \"notification\" node.");
+            LOGVAL(ctx, LYVE_DATA, "Missing the \"notification\" node.");
             ret = LY_EVALID;
             goto cleanup;
         }
diff --git a/src/parser_stmt.c b/src/parser_stmt.c
index 1ba3cdf..c36cbf6 100644
--- a/src/parser_stmt.c
+++ b/src/parser_stmt.c
@@ -845,8 +845,8 @@
 
     pctx.format = LYS_IN_YANG;
     pctx.parsed_mod = ctx->pmod;
-    pctx.pos_type = LY_VLOG_STR;
-    pctx.path = ctx->path;
+
+    LOG_LOCSET(ctx->ctx, NULL, NULL, ctx->path, NULL);
 
     switch (kw) {
     case LY_STMT_STATUS:
@@ -865,5 +865,6 @@
         return LY_EINT;
     }
 
+    LOG_LOCBACK(ctx->ctx, 0, 0, 1, 0);
     return ret;
 }
diff --git a/src/parser_xml.c b/src/parser_xml.c
index 15577c2..bca61af 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -79,7 +79,7 @@
             /* in XML, all attributes must be prefixed
              * TODO exception for NETCONF filters which are supposed to map to the ietf-netconf without prefix */
             if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Missing mandatory prefix for XML metadata \"%.*s\".",
+                LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Missing mandatory prefix for XML metadata \"%.*s\".",
                         xmlctx->name_len, xmlctx->name);
                 goto cleanup;
             }
@@ -95,15 +95,14 @@
         ns = lyxml_ns_get(&xmlctx->ns, xmlctx->prefix, xmlctx->prefix_len);
         if (!ns) {
             /* unknown namespace, XML error */
-            LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
-                    xmlctx->prefix_len, xmlctx->prefix);
+            LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", xmlctx->prefix_len, xmlctx->prefix);
             goto cleanup;
         }
         mod = ly_ctx_get_module_implemented_ns(xmlctx->ctx, ns->uri);
         if (!mod) {
             /* module is not implemented or not present in the schema */
             if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE,
+                LOGVAL(xmlctx->ctx, LYVE_REFERENCE,
                         "Unknown (or not implemented) YANG module with namespace \"%s\" for metadata \"%.*s%s%.*s\".",
                         ns->uri, xmlctx->prefix_len, xmlctx->prefix, xmlctx->prefix_len ? ":" : "", xmlctx->name_len,
                         xmlctx->name);
@@ -157,8 +156,7 @@
             /* get namespace of the attribute */
             ns = lyxml_ns_get(&xmlctx->ns, xmlctx->prefix, xmlctx->prefix_len);
             if (!ns) {
-                LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
-                        xmlctx->prefix_len, xmlctx->prefix);
+                LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", xmlctx->prefix_len, xmlctx->prefix);
                 ret = LY_EVALID;
                 goto cleanup;
             }
@@ -402,16 +400,14 @@
     /* get the element module */
     ns = lyxml_ns_get(&xmlctx->ns, prefix, prefix_len);
     if (!ns) {
-        LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
-                prefix_len, prefix);
+        LOGVAL(ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", prefix_len, prefix);
         ret = LY_EVALID;
         goto error;
     }
     mod = ly_ctx_get_module_implemented_ns(ctx, ns->uri);
     if (!mod) {
         if (lydctx->parse_options & LYD_PARSE_STRICT) {
-            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "No module with namespace \"%s\" in the context.",
-                    ns->uri);
+            LOGVAL(ctx, LYVE_REFERENCE, "No module with namespace \"%s\" in the context.", ns->uri);
             ret = LY_EVALID;
             goto error;
         }
@@ -431,8 +427,7 @@
         snode = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
         if (!snode) {
             if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Element \"%.*s\" not found in the \"%s\" module.",
-                        name_len, name, mod->name);
+                LOGVAL(ctx, LYVE_REFERENCE, "Element \"%.*s\" not found in the \"%s\" module.", name_len, name, mod->name);
                 ret = LY_EVALID;
                 goto error;
             } else if (!(lydctx->parse_options & LYD_PARSE_OPAQ)) {
@@ -492,14 +487,14 @@
         /* create node */
         LY_CHECK_GOTO(ret = lyd_parser_create_term((struct lyd_ctx *)lydctx, snode, xmlctx->value, xmlctx->value_len,
                 &xmlctx->dynamic, LY_PREF_XML, &xmlctx->ns, LYD_HINT_DATA, &node), error);
+        LOG_LOCSET(ctx, snode, node, NULL, NULL);
 
         if (parent && (node->schema->flags & LYS_KEY)) {
             /* check the key order, the anchor must never be a key */
             anchor = lyd_insert_get_next_anchor(parent->child, node);
             if (anchor && (anchor->schema->flags & LYS_KEY)) {
                 if (lydctx->parse_options & LYD_PARSE_STRICT) {
-                    LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_DATA, "Invalid position of the key \"%s\" in a list.",
-                            node->schema->name);
+                    LOGVAL(ctx, LYVE_DATA, "Invalid position of the key \"%s\" in a list.", node->schema->name);
                     ret = LY_EVALID;
                     goto error;
                 } else {
@@ -513,7 +508,7 @@
 
         /* no children expected */
         if (xmlctx->status == LYXML_ELEMENT) {
-            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Child element \"%.*s\" inside a terminal node \"%s\" found.",
+            LOGVAL(ctx, LYVE_SYNTAX, "Child element \"%.*s\" inside a terminal node \"%s\" found.",
                     xmlctx->name_len, xmlctx->name, snode->name);
             ret = LY_EVALID;
             goto error;
@@ -521,7 +516,7 @@
     } else if (snode->nodetype & LYD_NODE_INNER) {
         if (!xmlctx->ws_only) {
             /* value in inner node */
-            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an inner node \"%s\" found.",
+            LOGVAL(ctx, LYVE_SYNTAX, "Text value \"%.*s\" inside an inner node \"%s\" found.",
                     xmlctx->value_len, xmlctx->value, snode->name);
             ret = LY_EVALID;
             goto error;
@@ -531,6 +526,8 @@
         ret = lyd_create_inner(snode, &node);
         LY_CHECK_GOTO(ret, error);
 
+        LOG_LOCSET(ctx, snode, node, NULL, NULL);
+
         /* parser next */
         LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), error);
 
@@ -563,7 +560,7 @@
     } else if (snode->nodetype & LYD_NODE_ANY) {
         if (!xmlctx->ws_only) {
             /* value in inner node */
-            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an any node \"%s\" found.",
+            LOGVAL(ctx, LYVE_SYNTAX, "Text value \"%.*s\" inside an any node \"%s\" found.",
                     xmlctx->value_len, xmlctx->value, snode->name);
             ret = LY_EVALID;
             goto error;
@@ -611,9 +608,11 @@
         *first_p = (*first_p)->prev;
     }
 
+    LOG_LOCBACK(ctx, node ? 1 : 0, node ? 1 : 0, 0, 0);
     return LY_SUCCESS;
 
 error:
+    LOG_LOCBACK(ctx, node ? 1 : 0, node ? 1 : 0, 0, 0);
     lyd_free_meta_siblings(meta);
     lyd_free_attr_siblings(ctx, attr);
     lyd_free_tree(node);
@@ -654,6 +653,10 @@
         *tree_p = NULL;
     } else {
         *lydctx_p = (struct lyd_ctx *)lydctx;
+
+        /* the XML context is no more needed, freeing it also stops logging line numbers which would be confusing now */
+        lyxml_ctx_free(lydctx->xmlctx);
+        lydctx->xmlctx = NULL;
     }
     return ret;
 }
@@ -680,7 +683,7 @@
     prefix_len = xmlctx->prefix_len;
     ns = lyxml_ns_get(&xmlctx->ns, prefix, prefix_len);
     if (!ns) {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
+        LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
                 prefix_len, prefix);
         return LY_EVALID;
     } else if (strcmp(ns->uri, uri)) {
@@ -696,7 +699,7 @@
     }
 
     if (!xmlctx->ws_only) {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Unexpected value \"%.*s\" in the \"%s\" element.",
+        LOGVAL(xmlctx->ctx, LYVE_SYNTAX, "Unexpected value \"%.*s\" in the \"%s\" element.",
                 xmlctx->value_len, xmlctx->value, name);
         ret = LY_EVALID;
         goto cleanup;
@@ -748,11 +751,11 @@
 
     /* make sure we have parsed some operation and it is the only subtree */
     if (!lydctx.op_node) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_DATA, "Missing the \"rpc\"/\"action\" node.");
+        LOGVAL(ctx, LYVE_DATA, "Missing the \"rpc\"/\"action\" node.");
         ret = LY_EVALID;
         goto cleanup;
     } else if (lydctx.xmlctx->status == LYXML_ELEMENT) {
-        LOGVAL(ctx, LY_VLOG_LINE, &lydctx.xmlctx->in->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
+        LOGVAL(ctx, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
                 tree->schema->name);
         ret = LY_EVALID;
         goto cleanup;
@@ -800,7 +803,7 @@
 
     /* child "eventTime" */
     if ((xmlctx->status != LYXML_ELEMENT) || ly_strncmp("eventTime", xmlctx->name, xmlctx->name_len)) {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Missing the \"eventTime\" element.");
+        LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Missing the \"eventTime\" element.");
         ret = LY_EVALID;
         goto cleanup;
     }
@@ -809,13 +812,11 @@
     prefix_len = xmlctx->prefix_len;
     ns = lyxml_ns_get(&xmlctx->ns, prefix, prefix_len);
     if (!ns) {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
-                prefix_len, prefix);
+        LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".", prefix_len, prefix);
         ret = LY_EVALID;
         goto cleanup;
     } else if (strcmp(ns->uri, "urn:ietf:params:xml:ns:netconf:notification:1.0")) {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Invalid namespace \"%s\" of \"eventTime\".",
-                ns->uri);
+        LOGVAL(xmlctx->ctx, LYVE_REFERENCE, "Invalid namespace \"%s\" of \"eventTime\".", ns->uri);
         ret = LY_EVALID;
         goto cleanup;
     }
@@ -852,7 +853,7 @@
     LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
     if (xmlctx->status != LYXML_ELEM_CLOSE) {
         assert(xmlctx->status == LYXML_ELEMENT);
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Unexpected sibling element \"%.*s\" of \"eventTime\".",
+        LOGVAL(xmlctx->ctx, LYVE_SYNTAX, "Unexpected sibling element \"%.*s\" of \"eventTime\".",
                 xmlctx->name_len, xmlctx->name);
         ret = LY_EVALID;
         goto cleanup;
@@ -891,11 +892,11 @@
 
     /* make sure we have parsed some notification */
     if (!lydctx.op_node) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_DATA, "Missing the \"notification\" node.");
+        LOGVAL(ctx, LYVE_DATA, "Missing the \"notification\" node.");
         ret = LY_EVALID;
         goto cleanup;
     } else if (lydctx.xmlctx->status == LYXML_ELEMENT) {
-        LOGVAL(ctx, LY_VLOG_LINE, &lydctx.xmlctx->in->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
+        LOGVAL(ctx, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
                 tree->schema->name);
         ret = LY_EVALID;
         goto cleanup;
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 71dd843..f3d98fe 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -4477,7 +4477,6 @@
     LY_CHECK_ERR_RET(!(*context), LOGMEM(ly_ctx), LY_EMEM);
     (*context)->format = LYS_IN_YANG;
     (*context)->unres = main_ctx->unres;
-    (*context)->pos_type = LY_VLOG_LINE;
     (*context)->in = in;
 
     mod_p = calloc(1, sizeof *mod_p);
@@ -4486,6 +4485,8 @@
     mod_p->parsing = 1;
     (*context)->parsed_mod = (struct lysp_module *)mod_p;
 
+    LOG_LOCINIT(PARSER_CTX(*context), NULL, NULL, NULL, in);
+
     /* map the typedefs and groupings list from main context to the submodule's context */
     memcpy(&(*context)->tpdfs_nodes, &main_ctx->tpdfs_nodes, sizeof main_ctx->tpdfs_nodes);
     memcpy(&(*context)->grps_nodes, &main_ctx->grps_nodes, sizeof main_ctx->grps_nodes);
@@ -4525,6 +4526,7 @@
     *submod = mod_p;
 
 cleanup:
+    LOG_LOCBACK(PARSER_CTX(*context), 0, 0, 0, 1);
     if (ret) {
         lysp_module_free((struct lysp_module *)mod_p);
         yang_parser_ctx_free(*context);
@@ -4548,7 +4550,6 @@
     LY_CHECK_ERR_RET(!(*context), LOGMEM(mod->ctx), LY_EMEM);
     (*context)->format = LYS_IN_YANG;
     (*context)->unres = unres;
-    (*context)->pos_type = LY_VLOG_LINE;
     (*context)->in = in;
 
     mod_p = calloc(1, sizeof *mod_p);
@@ -4557,6 +4558,8 @@
     mod_p->parsing = 1;
     (*context)->parsed_mod = mod_p;
 
+    LOG_LOCINIT(PARSER_CTX(*context), NULL, NULL, NULL, in);
+
     /* skip redundant but valid characters at the beginning */
     ret = skip_redundant_chars(*context);
     LY_CHECK_GOTO(ret, cleanup);
@@ -4592,6 +4595,7 @@
     mod->parsed = mod_p;
 
 cleanup:
+    LOG_LOCBACK(PARSER_CTX(*context), 0, 0, 0, 1);
     if (ret) {
         lysp_module_free(mod_p);
         yang_parser_ctx_free(*context);
diff --git a/src/path.c b/src/path.c
index 10e9ec1..df3abc3 100644
--- a/src/path.c
+++ b/src/path.c
@@ -54,6 +54,8 @@
     const char *name;
     size_t name_len;
 
+    LOG_LOCSET(ctx, cur_node, NULL, NULL, NULL);
+
     if (!lyxp_next_token(NULL, exp, tok_idx, LYXP_TOKEN_BRACK1)) {
         /* '[' */
 
@@ -69,11 +71,11 @@
                 /* check prefix based on the options */
                 name = strnstr(exp->expr + exp->tok_pos[*tok_idx], ":", exp->tok_len[*tok_idx]);
                 if ((prefix == LY_PATH_PREFIX_MANDATORY) && !name) {
-                    LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", exp->tok_len[*tok_idx],
+                    LOGVAL(ctx, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", exp->tok_len[*tok_idx],
                             exp->expr + exp->tok_pos[*tok_idx]);
                     goto token_error;
                 } else if ((prefix == LY_PATH_PREFIX_STRICT_INHERIT) && name) {
-                    LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Redundant prefix for \"%.*s\" in path.", exp->tok_len[*tok_idx],
+                    LOGVAL(ctx, LYVE_XPATH, "Redundant prefix for \"%.*s\" in path.", exp->tok_len[*tok_idx],
                             exp->expr + exp->tok_pos[*tok_idx]);
                     goto token_error;
                 }
@@ -89,7 +91,7 @@
                 for (i = 0; i < set->count; ++i) {
                     /* all the keys must be from the same module so this comparison should be fine */
                     if (!strncmp(set->objs[i], name, name_len) && !isalpha(((char *)set->objs[i])[name_len])) {
-                        LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Duplicate predicate key \"%.*s\" in path.", name_len, name);
+                        LOGVAL(ctx, LYVE_XPATH, "Duplicate predicate key \"%.*s\" in path.", name_len, name);
                         goto token_error;
                     }
                 }
@@ -153,7 +155,7 @@
                 for (i = 0; i < set->count; ++i) {
                     /* all the keys must be from the same module so this comparison should be fine */
                     if (!strncmp(set->objs[i], name, name_len) && !isalpha(((char *)set->objs[i])[name_len])) {
-                        LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Duplicate predicate key \"%.*s\" in path.", name_len, name);
+                        LOGVAL(ctx, LYVE_XPATH, "Duplicate predicate key \"%.*s\" in path.", name_len, name);
                         goto token_error;
                     }
                 }
@@ -172,7 +174,7 @@
                 LY_CHECK_GOTO(lyxp_check_token(ctx, exp, *tok_idx, LYXP_TOKEN_FUNCNAME), token_error);
                 if ((exp->tok_len[*tok_idx] != ly_strlen_const("current")) ||
                         strncmp(exp->expr + exp->tok_pos[*tok_idx], "current", ly_strlen_const("current"))) {
-                    LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Invalid function \"%.*s\" invocation in path.",
+                    LOGVAL(ctx, LYVE_XPATH, "Invalid function \"%.*s\" invocation in path.",
                             exp->tok_len[*tok_idx], exp->expr + exp->tok_pos[*tok_idx]);
                     goto token_error;
                 }
@@ -210,17 +212,18 @@
             } while (!lyxp_next_token(NULL, exp, tok_idx, LYXP_TOKEN_BRACK1));
 
         } else {
-            LOGVAL_P(ctx, cur_node, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]),
-                    exp->expr + exp->tok_pos[*tok_idx]);
+            LOGVAL(ctx, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]), exp->expr + exp->tok_pos[*tok_idx]);
             goto token_error;
         }
     }
 
 cleanup:
+    LOG_LOCBACK(ctx, cur_node ? 1 : 0, 0, 0, 0);
     ly_set_free(set, NULL);
     return ret;
 
 token_error:
+    LOG_LOCBACK(ctx, cur_node ? 1 : 0, 0, 0, 0);
     ly_set_free(set, NULL);
     return LY_EVALID;
 }
@@ -240,6 +243,8 @@
             (prefix == LY_PATH_PREFIX_STRICT_INHERIT));
     assert((pred == LY_PATH_PRED_KEYS) || (pred == LY_PATH_PRED_SIMPLE) || (pred == LY_PATH_PRED_LEAFREF));
 
+    LOG_LOCSET(ctx, ctx_node, NULL, NULL, NULL);
+
     /* parse as a generic XPath expression */
     LY_CHECK_GOTO(ret = lyxp_expr_parse(ctx, str_path, path_len, 1, &exp), error);
     tok_idx = 0;
@@ -274,7 +279,7 @@
         cur_len = exp->tok_len[tok_idx];
         if (prefix == LY_PATH_PREFIX_MANDATORY) {
             if (!strnstr(cur_node, ":", cur_len)) {
-                LOGVAL_P(ctx, ctx_node, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", cur_len, cur_node);
+                LOGVAL(ctx, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", cur_len, cur_node);
                 ret = LY_EVALID;
                 goto error;
             }
@@ -282,7 +287,7 @@
             if (!prev_prefix) {
                 /* the first node must have a prefix */
                 if (!strnstr(cur_node, ":", cur_len)) {
-                    LOGVAL_P(ctx, ctx_node, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", cur_len, cur_node);
+                    LOGVAL(ctx, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", cur_len, cur_node);
                     ret = LY_EVALID;
                     goto error;
                 }
@@ -294,7 +299,7 @@
                 ptr = strnstr(cur_node, ":", cur_len);
                 if (ptr) {
                     if (!strncmp(prev_prefix, cur_node, ptr - cur_node) && (prev_prefix[ptr - cur_node] == ':')) {
-                        LOGVAL_P(ctx, ctx_node, LYVE_XPATH, "Duplicate prefix for \"%.*s\" in path.", cur_len, cur_node);
+                        LOGVAL(ctx, LYVE_XPATH, "Duplicate prefix for \"%.*s\" in path.", cur_len, cur_node);
                         ret = LY_EVALID;
                         goto error;
                     }
@@ -315,17 +320,19 @@
 
     /* trailing token check */
     if (exp->used > tok_idx) {
-        LOGVAL_P(ctx, ctx_node, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of path.",
-                exp->expr + exp->tok_pos[tok_idx]);
+        LOGVAL(ctx, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of path.", exp->expr + exp->tok_pos[tok_idx]);
         ret = LY_EVALID;
         goto error;
     }
 
     *expr = exp;
+
+    LOG_LOCBACK(ctx, ctx_node ? 1 : 0, 0, 0, 0);
     return LY_SUCCESS;
 
 error:
     lyxp_expr_free(ctx, exp);
+    LOG_LOCBACK(ctx, ctx_node ? 1 : 0, 0, 0, 0);
     return ret;
 }
 
@@ -340,6 +347,8 @@
     assert((prefix == LY_PATH_PREFIX_OPTIONAL) || (prefix == LY_PATH_PREFIX_MANDATORY));
     assert((pred == LY_PATH_PRED_KEYS) || (pred == LY_PATH_PRED_SIMPLE) || (pred == LY_PATH_PRED_LEAFREF));
 
+    LOG_LOCSET(ctx, cur_node, NULL, NULL, NULL);
+
     /* parse as a generic XPath expression */
     LY_CHECK_GOTO(ret = lyxp_expr_parse(ctx, str_path, path_len, 0, &exp), error);
     tok_idx = 0;
@@ -348,17 +357,20 @@
 
     /* trailing token check */
     if (exp->used > tok_idx) {
-        LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of predicate.",
+        LOGVAL(ctx, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of predicate.",
                 exp->expr + exp->tok_pos[tok_idx]);
         ret = LY_EVALID;
         goto error;
     }
 
     *expr = exp;
+
+    LOG_LOCBACK(ctx, cur_node ? 1 : 0, 0, 0, 0);
     return LY_SUCCESS;
 
 error:
     lyxp_expr_free(ctx, exp);
+    LOG_LOCBACK(ctx, cur_node ? 1 : 0, 0, 0, 0);
     return ret;
 }
 
@@ -385,6 +397,7 @@
         LY_PREFIX_FORMAT format, void *prefix_data, struct lys_glob_unres *unres, const struct lys_module **mod,
         const char **name, size_t *name_len)
 {
+    LY_ERR ret;
     const char *pref;
     size_t len;
 
@@ -401,18 +414,24 @@
 
     /* find next node module */
     if (pref) {
+        ret = LY_EVALID;
+
+        LOG_LOCSET(ctx, cur_node, NULL, NULL, NULL);
+
         *mod = ly_resolve_prefix(ctx, pref, len, format, prefix_data);
         if (!*mod) {
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "No module connected with the prefix \"%.*s\" found (prefix format %s).",
+            LOGVAL(ctx, LYVE_XPATH, "No module connected with the prefix \"%.*s\" found (prefix format %s).",
                     len, pref, ly_format2str(format));
-            return LY_EVALID;
+            goto error;
         } else if (!(*mod)->implemented) {
             if (lref == LY_PATH_LREF_FALSE) {
-                LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Not implemented module \"%s\" in path.", (*mod)->name);
-                return LY_EVALID;
+                LOGVAL(ctx, LYVE_XPATH, "Not implemented module \"%s\" in path.", (*mod)->name);
+                goto error;
             }
-            LY_CHECK_RET(lys_set_implemented_r((struct lys_module *)*mod, NULL, unres));
+            LY_CHECK_GOTO(ret = lys_set_implemented_r((struct lys_module *)*mod, NULL, unres), error);
         }
+
+        LOG_LOCBACK(ctx, cur_node ? 1 : 0, 0, 0, 0);
     } else {
         switch (format) {
         case LY_PREF_SCHEMA:
@@ -446,6 +465,10 @@
     }
 
     return LY_SUCCESS;
+
+error:
+    LOG_LOCBACK(ctx, cur_node ? 1 : 0, 0, 0, 0);
+    return LY_EVALID;
 }
 
 LY_ERR
@@ -453,6 +476,7 @@
         const struct lysc_node *ctx_node, const struct lyxp_expr *expr, uint16_t *tok_idx, LY_PREFIX_FORMAT format,
         void *prefix_data, struct ly_path_predicate **predicates, enum ly_path_pred_type *pred_type)
 {
+    LY_ERR ret = LY_SUCCESS;
     struct ly_path_predicate *p;
     const struct lysc_node *key;
     const struct lys_module *mod = NULL;
@@ -461,22 +485,26 @@
 
     assert(ctx && ctx_node);
 
+    LOG_LOCSET(ctx, cur_node, NULL, NULL, NULL);
+
     *pred_type = 0;
 
     if (lyxp_next_token(NULL, expr, tok_idx, LYXP_TOKEN_BRACK1)) {
         /* '[', no predicate */
-        return LY_SUCCESS;
+        goto cleanup; /* LY_SUCCESS */
     }
 
     if (expr->tokens[*tok_idx] == LYXP_TOKEN_NAMETEST) {
         if (ctx_node->nodetype != LYS_LIST) {
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "List predicate defined for %s \"%s\" in path.",
+            LOGVAL(ctx, LYVE_XPATH, "List predicate defined for %s \"%s\" in path.",
                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
-            return LY_EVALID;
+            ret = LY_EVALID;
+            goto cleanup;
         } else if (ctx_node->flags & LYS_KEYLESS) {
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "List predicate defined for keyless %s \"%s\" in path.",
+            LOGVAL(ctx, LYVE_XPATH, "List predicate defined for keyless %s \"%s\" in path.",
                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
-            return LY_EVALID;
+            ret = LY_EVALID;
+            goto cleanup;
         }
 
         do {
@@ -485,12 +513,14 @@
                     format, prefix_data, NULL, &mod, &name, &name_len));
             key = lys_find_child(ctx_node, mod, name, name_len, 0, 0);
             if (!key) {
-                LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
-                return LY_ENOTFOUND;
+                LOGVAL(ctx, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
+                ret = LY_ENOTFOUND;
+                goto cleanup;
             } else if ((key->nodetype != LYS_LEAF) || !(key->flags & LYS_KEY)) {
-                LOGVAL_P(ctx, cur_node ? cur_node : key, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.",
-                        lys_nodetype2str(key->nodetype), key->name);
-                return LY_EVALID;
+                LOGVAL(ctx, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.", lys_nodetype2str(key->nodetype),
+                        key->name);
+                ret = LY_EVALID;
+                goto cleanup;
             }
             ++(*tok_idx);
 
@@ -499,7 +529,7 @@
                 *pred_type = LY_PATH_PREDTYPE_LIST;
             }
             assert(*pred_type == LY_PATH_PREDTYPE_LIST);
-            LY_ARRAY_NEW_RET(ctx, *predicates, p, LY_EMEM);
+            LY_ARRAY_NEW_GOTO(ctx, *predicates, p, ret, cleanup);
             p->key = key;
 
             /* '=' */
@@ -508,9 +538,12 @@
 
             /* Literal */
             assert(expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL);
-            LY_CHECK_RET(lyd_value_store(ctx, &p->value, ((struct lysc_node_leaf *)key)->type,
+            LOG_LOCSET(ctx, key, NULL, NULL, NULL);
+            ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaf *)key)->type,
                     expr->expr + expr->tok_pos[*tok_idx] + 1, expr->tok_len[*tok_idx] - 2, NULL, format, prefix_data,
-                    LYD_HINT_DATA, key, NULL, LY_VLOG_LYSC, key));
+                    LYD_HINT_DATA, key, NULL);
+            LOG_LOCBACK(ctx, key ? 1 : 0, 0, 0, 0);
+            LY_CHECK_GOTO(ret, cleanup);
             ++(*tok_idx);
 
             /* "allocate" the type to avoid problems when freeing the value after the type was freed */
@@ -530,24 +563,26 @@
         }
         if (LY_ARRAY_COUNT(*predicates) != key_count) {
             /* names (keys) are unique - it was checked when parsing */
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Predicate missing for a key of %s \"%s\" in path.",
+            LOGVAL(ctx, LYVE_XPATH, "Predicate missing for a key of %s \"%s\" in path.",
                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
             ly_path_predicates_free(ctx, LY_PATH_PREDTYPE_LIST, *predicates);
             *predicates = NULL;
-            return LY_EVALID;
+            ret = LY_EVALID;
+            goto cleanup;
         }
 
     } else if (expr->tokens[*tok_idx] == LYXP_TOKEN_DOT) {
         if (ctx_node->nodetype != LYS_LEAFLIST) {
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Leaf-list predicate defined for %s \"%s\" in path.",
+            LOGVAL(ctx, LYVE_XPATH, "Leaf-list predicate defined for %s \"%s\" in path.",
                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
-            return LY_EVALID;
+            ret = LY_EVALID;
+            goto cleanup;
         }
         ++(*tok_idx);
 
         /* new predicate */
         *pred_type = LY_PATH_PREDTYPE_LEAFLIST;
-        LY_ARRAY_NEW_RET(ctx, *predicates, p, LY_EMEM);
+        LY_ARRAY_NEW_GOTO(ctx, *predicates, p, ret, cleanup);
 
         /* '=' */
         assert(expr->tokens[*tok_idx] == LYXP_TOKEN_OPER_EQUAL);
@@ -555,9 +590,12 @@
 
         assert(expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL);
         /* store the value */
-        LY_CHECK_RET(lyd_value_store(ctx, &p->value, ((struct lysc_node_leaflist *)ctx_node)->type,
+        LOG_LOCSET(ctx, ctx_node, NULL, NULL, NULL);
+        ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaflist *)ctx_node)->type,
                 expr->expr + expr->tok_pos[*tok_idx] + 1, expr->tok_len[*tok_idx] - 2, NULL, format, prefix_data,
-                LYD_HINT_DATA, ctx_node, NULL, LY_VLOG_LYSC, ctx_node));
+                LYD_HINT_DATA, ctx_node, NULL);
+        LOG_LOCBACK(ctx, ctx_node ? 1 : 0, 0, 0, 0);
+        LY_CHECK_GOTO(ret, cleanup);
         ++(*tok_idx);
 
         /* "allocate" the type to avoid problems when freeing the value after the type was freed */
@@ -569,18 +607,20 @@
     } else {
         assert(expr->tokens[*tok_idx] == LYXP_TOKEN_NUMBER);
         if (!(ctx_node->nodetype & (LYS_LEAFLIST | LYS_LIST))) {
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Positional predicate defined for %s \"%s\" in path.",
+            ret = LY_EVALID;
+            LOGVAL(ctx, LYVE_XPATH, "Positional predicate defined for %s \"%s\" in path.",
                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
-            return LY_EVALID;
+            goto cleanup;
         } else if (ctx_node->flags & LYS_CONFIG_W) {
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Positional predicate defined for configuration %s \"%s\" in path.",
+            ret = LY_EVALID;
+            LOGVAL(ctx, LYVE_XPATH, "Positional predicate defined for configuration %s \"%s\" in path.",
                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
-            return LY_EVALID;
+            goto cleanup;
         }
 
         /* new predicate */
         *pred_type = LY_PATH_PREDTYPE_POSITION;
-        LY_ARRAY_NEW_RET(ctx, *predicates, p, LY_EMEM);
+        LY_ARRAY_NEW_GOTO(ctx, *predicates, p, ret, cleanup);
 
         /* syntax was already checked */
         p->position = strtoull(expr->expr + expr->tok_pos[*tok_idx], (char **)&name, LY_BASE_DEC);
@@ -591,7 +631,9 @@
         ++(*tok_idx);
     }
 
-    return LY_SUCCESS;
+cleanup:
+    LOG_LOCBACK(ctx, cur_node ? 1 : 0, 0, 0, 0);
+    return ret;
 }
 
 /**
@@ -611,38 +653,47 @@
         const struct lyxp_expr *expr, uint16_t *tok_idx, LY_PREFIX_FORMAT format, void *prefix_data,
         struct lys_glob_unres *unres)
 {
+    LY_ERR ret = LY_SUCCESS;
     const struct lysc_node *key, *node, *node2;
     const struct lys_module *mod;
     const char *name;
     size_t name_len;
+    struct ly_ctx *ctx = cur_node->module->ctx;
+
+    LOG_LOCSET(ctx, cur_node, NULL, NULL, NULL);
 
     if (lyxp_next_token(NULL, expr, tok_idx, LYXP_TOKEN_BRACK1)) {
         /* '[', no predicate */
-        return LY_SUCCESS;
+        goto cleanup; /* LY_SUCCESS */
     }
 
     if (ctx_node->nodetype != LYS_LIST) {
-        LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "List predicate defined for %s \"%s\" in path.",
+        LOGVAL(ctx, LYVE_XPATH, "List predicate defined for %s \"%s\" in path.",
                 lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
-        return LY_EVALID;
+        ret = LY_EVALID;
+        goto cleanup;
     } else if (ctx_node->flags & LYS_KEYLESS) {
-        LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "List predicate defined for keyless %s \"%s\" in path.",
+        LOGVAL(ctx, LYVE_XPATH, "List predicate defined for keyless %s \"%s\" in path.",
                 lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
-        return LY_EVALID;
+        ret = LY_EVALID;
+        goto cleanup;
     }
 
     do {
         /* NameTest, find the key */
-        LY_CHECK_RET(ly_path_compile_prefix(cur_node->module->ctx, cur_node, cur_node->module, ctx_node, expr, *tok_idx,
-                LY_PATH_LREF_TRUE, format, prefix_data, unres, &mod, &name, &name_len));
+        ret = ly_path_compile_prefix(ctx, cur_node, cur_node->module, ctx_node, expr, *tok_idx,
+                LY_PATH_LREF_TRUE, format, prefix_data, unres, &mod, &name, &name_len);
+        LY_CHECK_GOTO(ret, cleanup);
         key = lys_find_child(ctx_node, mod, name, name_len, 0, 0);
         if (!key) {
-            LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
-            return LY_EVALID;
+            LOGVAL(ctx, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
+            ret = LY_EVALID;
+            goto cleanup;
         } else if ((key->nodetype != LYS_LEAF) || !(key->flags & LYS_KEY)) {
-            LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.",
+            LOGVAL(ctx, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.",
                     lys_nodetype2str(key->nodetype), key->name);
-            return LY_EVALID;
+            ret = LY_EVALID;
+            goto cleanup;
         }
         ++(*tok_idx);
 
@@ -675,8 +726,9 @@
 
             /* go to parent */
             if (!node) {
-                LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "Too many parent references in path.");
-                return LY_EVALID;
+                LOGVAL(ctx, LYVE_XPATH, "Too many parent references in path.");
+                ret = LY_EVALID;
+                goto cleanup;
             }
             node = lysc_data_parent(node);
 
@@ -692,12 +744,13 @@
 
             /* NameTest */
             assert(expr->tokens[*tok_idx] == LYXP_TOKEN_NAMETEST);
-            LY_CHECK_RET(ly_path_compile_prefix(cur_node->module->ctx, cur_node, cur_node->module, node, expr, *tok_idx,
+            LY_CHECK_RET(ly_path_compile_prefix(ctx, cur_node, cur_node->module, node, expr, *tok_idx,
                     LY_PATH_LREF_TRUE, format, prefix_data, unres, &mod, &name, &name_len));
             node2 = lys_find_child(node, mod, name, name_len, 0, 0);
             if (!node2) {
-                LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
-                return LY_EVALID;
+                LOGVAL(ctx, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
+                ret = LY_EVALID;
+                goto cleanup;
             }
             node = node2;
             ++(*tok_idx);
@@ -705,10 +758,10 @@
 
         /* check the last target node */
         if (node->nodetype != LYS_LEAF) {
-            LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH,
-                    "Leaf expected instead of %s \"%s\" in leafref predicate in path.",
+            LOGVAL(ctx, LYVE_XPATH, "Leaf expected instead of %s \"%s\" in leafref predicate in path.",
                     lys_nodetype2str(node->nodetype), node->name);
-            return LY_EVALID;
+            ret = LY_EVALID;
+            goto cleanup;
         }
 
         /* we are not actually compiling, throw the rightside node away */
@@ -721,7 +774,9 @@
         /* another predicate follows? */
     } while (!lyxp_next_token(NULL, expr, tok_idx, LYXP_TOKEN_BRACK1));
 
-    return LY_SUCCESS;
+cleanup:
+    LOG_LOCBACK(ctx, 1, 0, 0, 0);
+    return ret;
 }
 
 LY_ERR
@@ -747,10 +802,11 @@
     /* find operation, if we are in any */
     for (op = ctx_node; op && !(op->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)); op = op->parent) {}
 
+    *path = NULL;
+
     /* remember original context node */
     cur_node = ctx_node;
-
-    *path = NULL;
+    LOG_LOCINIT(ctx, cur_node, NULL, NULL, NULL);
 
     if (oper == LY_PATH_OPER_OUTPUT) {
         getnext_opts = LYS_GETNEXT_OUTPUT;
@@ -767,7 +823,7 @@
         /* relative path */
         while ((lref == LY_PATH_LREF_TRUE) && (expr->tokens[tok_idx] == LYXP_TOKEN_DDOT)) {
             if (!ctx_node) {
-                LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Too many parent references in path.");
+                LOGVAL(ctx, LYVE_XPATH, "Too many parent references in path.");
                 ret = LY_EVALID;
                 goto cleanup;
             }
@@ -789,7 +845,7 @@
         /* check last compiled inner node, whether it is uniquely identified (even key-less list) */
         if (p && (lref == LY_PATH_LREF_FALSE) && (target == LY_PATH_TARGET_SINGLE) &&
                 (p->node->nodetype == LYS_LIST) && !p->predicates) {
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
+            LOGVAL(ctx, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
                     lys_nodetype2str(p->node->nodetype), p->node->name);
             ret = LY_EVALID;
             goto cleanup;
@@ -806,7 +862,7 @@
         /* find the next node */
         node2 = lys_find_child(ctx_node, mod, name, name_len, 0, getnext_opts);
         if (!node2 || (op && (node2->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && (node2 != op))) {
-            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
+            LOGVAL(ctx, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
             ret = LY_EVALID;
             goto cleanup;
         }
@@ -828,8 +884,7 @@
 
     /* check leftover tokens */
     if (tok_idx < expr->used) {
-        LOGVAL_P(ctx, cur_node, LY_VCODE_XP_INTOK, lyxp_print_token(expr->tokens[tok_idx]),
-                &expr->expr[expr->tok_pos[tok_idx]]);
+        LOGVAL(ctx, LY_VCODE_XP_INTOK, lyxp_print_token(expr->tokens[tok_idx]), &expr->expr[expr->tok_pos[tok_idx]]);
         ret = LY_EVALID;
         goto cleanup;
     }
@@ -837,7 +892,7 @@
     /* check last compiled node */
     if ((lref == LY_PATH_LREF_FALSE) && (target == LY_PATH_TARGET_SINGLE) &&
             (p->node->nodetype & (LYS_LIST | LYS_LEAFLIST)) && !p->predicates) {
-        LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
+        LOGVAL(ctx, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
                 lys_nodetype2str(p->node->nodetype), p->node->name);
         ret = LY_EVALID;
         goto cleanup;
@@ -848,6 +903,7 @@
         ly_path_free(ctx, *path);
         *path = NULL;
     }
+    LOG_LOCBACK(ctx, 1, 0, 0, 0);
     return ret;
 }
 
diff --git a/src/schema_compile.c b/src/schema_compile.c
index ecc1a86..bd234f1 100644
--- a/src/schema_compile.c
+++ b/src/schema_compile.c
@@ -74,6 +74,10 @@
     *ext = lysc_ext_dup(ext_p->compiled);
 
 done:
+    if (ret) {
+        lysc_update_path(ctx, NULL, NULL);
+        lysc_update_path(ctx, NULL, NULL);
+    }
     return ret;
 }
 
@@ -120,7 +124,7 @@
             }
         }
         if (!prefixed_name) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid XML prefix of \"%.*s\" namespace used for extension instance identifier.", u, ext_p->name);
             ret = LY_EVALID;
             goto cleanup;
@@ -133,12 +137,12 @@
     if (!ext_mod) {
         ext_mod = u ? ly_resolve_prefix(ctx->ctx, prefixed_name, u - 1, LY_PREF_SCHEMA, ctx->pmod) : ctx->pmod->mod;
         if (!ext_mod) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid prefix \"%.*s\" used for extension instance identifier.", u, prefixed_name);
             ret = LY_EVALID;
             goto cleanup;
         } else if (!ext_mod->parsed->extensions) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Extension instance \"%s\" refers \"%s\" module that does not contain extension definitions.",
                     prefixed_name, ext_mod->name);
             ret = LY_EVALID;
@@ -156,7 +160,7 @@
         }
     }
     if (!ext->def) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+        LOGVAL(ctx->ctx, LYVE_REFERENCE,
                 "Extension definition of extension instance \"%s\" not found.", prefixed_name);
         ret = LY_EVALID;
         goto cleanup;
@@ -189,7 +193,7 @@
         }
         if (!stmt) {
             /* missing extension's argument */
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Extension instance \"%s\" misses argument \"%s\".", prefixed_name, ext->def->argument);
             ret = LY_EVALID;
             goto cleanup;
@@ -218,13 +222,14 @@
     ext_p->compiled = ext;
 
 cleanup:
-    if (prefixed_name && (prefixed_name != ext_p->name)) {
-        lydict_remove(ctx->ctx, prefixed_name);
+    lysc_update_path(ctx, NULL, NULL);
+    if (prefixed_name) {
+        lysc_update_path(ctx, NULL, NULL);
+        if (prefixed_name != ext_p->name) {
+            lydict_remove(ctx->ctx, prefixed_name);
+        }
     }
 
-    lysc_update_path(ctx, NULL, NULL);
-    lysc_update_path(ctx, NULL, NULL);
-
     return ret;
 }
 
@@ -303,6 +308,9 @@
             ctx->path_len += len;
         }
     }
+
+    LOG_LOCBACK(ctx->ctx, 0, 0, 1, 0);
+    LOG_LOCSET(ctx->ctx, NULL, NULL, ctx->path, NULL);
 }
 
 /**
@@ -428,7 +436,7 @@
 
     for (u = 0; u < LY_ARRAY_COUNT(derived); ++u) {
         if (ident == derived[u]) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Identity \"%s\" is indirectly derived from itself.", ident->name);
             ret = LY_EVALID;
             goto cleanup;
@@ -441,7 +449,7 @@
         drv = recursion.objs[v];
         for (u = 0; u < LY_ARRAY_COUNT(drv->derived); ++u) {
             if (ident == drv->derived[u]) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                LOGVAL(ctx->ctx, LYVE_REFERENCE,
                         "Identity \"%s\" is indirectly derived from itself.", ident->name);
                 ret = LY_EVALID;
                 goto cleanup;
@@ -468,7 +476,7 @@
     assert((ident && enabled) || bases);
 
     if ((LY_ARRAY_COUNT(bases_p) > 1) && (ctx->pmod->version < LYS_VERSION_1_1)) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                 "Multiple bases in %s are allowed only in YANG 1.1 modules.", ident ? "identity" : "identityref type");
         return LY_EVALID;
     }
@@ -485,10 +493,10 @@
         }
         if (!mod) {
             if (ident) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Invalid prefix used for base (%s) of identity \"%s\".", bases_p[u], ident->name);
             } else {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Invalid prefix used for base (%s) of identityref.", bases_p[u]);
             }
             return LY_EVALID;
@@ -499,7 +507,7 @@
             if (!strcmp(name, mod->identities[v].name)) {
                 if (ident) {
                     if (ident == &mod->identities[v]) {
-                        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                        LOGVAL(ctx->ctx, LYVE_REFERENCE,
                                 "Identity \"%s\" is derived from itself.", ident->name);
                         return LY_EVALID;
                     }
@@ -524,10 +532,10 @@
                         return LY_SUCCESS;
                     }
                 }
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Unable to find base (%s) of identity \"%s\".", bases_p[u], ident->name);
             } else {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Unable to find base (%s) of identityref.", bases_p[u]);
             }
             return LY_EVALID;
@@ -635,7 +643,7 @@
             }
         }
         if (!substmts[u].stmt) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid keyword \"%s\" as a child of \"%s%s%s\" extension instance.",
+            LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Invalid keyword \"%s\" as a child of \"%s%s%s\" extension instance.",
                     stmt->stmt, ext->name, ext->argument ? " " : "", ext->argument ? ext->argument : "");
             goto cleanup;
         }
@@ -666,7 +674,7 @@
                     if (substmts[u].cardinality < LY_STMT_CARD_SOME) {
                         /* single item */
                         if (*((const char **)substmts[u].storage)) {
-                            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_DUPSTMT, stmt->stmt);
+                            LOGVAL(ctx->ctx, LY_VCODE_DUPSTMT, stmt->stmt);
                             goto cleanup;
                         }
                         units = (const char **)substmts[u].storage;
@@ -686,7 +694,7 @@
                     if (substmts[u].cardinality < LY_STMT_CARD_SOME) {
                         /* single item */
                         if (*(struct lysc_type **)substmts[u].storage) {
-                            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_DUPSTMT, stmt->stmt);
+                            LOGVAL(ctx->ctx, LY_VCODE_DUPSTMT, stmt->stmt);
                             goto cleanup;
                         }
                         compiled = substmts[u].storage;
@@ -722,7 +730,7 @@
                 /* TODO support other substatements (parse stmt to lysp and then compile lysp to lysc),
                  * also note that in many statements their extensions are not taken into account  */
                 default:
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Statement \"%s\" is not supported as an extension (found in \"%s%s%s\") substatement.",
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Statement \"%s\" is not supported as an extension (found in \"%s%s%s\") substatement.",
                             stmt->stmt, ext->name, ext->argument ? " " : "", ext->argument ? ext->argument : "");
                     goto cleanup;
                 }
@@ -730,7 +738,7 @@
         }
 
         if (((substmts[u].cardinality == LY_STMT_CARD_MAND) || (substmts[u].cardinality == LY_STMT_CARD_SOME)) && !stmt_present) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Missing mandatory keyword \"%s\" as a child of \"%s%s%s\".",
+            LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Missing mandatory keyword \"%s\" as a child of \"%s%s%s\".",
                     ly_stmt2str(substmts[u].stmt), ext->name, ext->argument ? " " : "", ext->argument ? ext->argument : "");
             goto cleanup;
         }
@@ -787,12 +795,13 @@
 
         node = xp_scnode->scnode;
         do {
+            LOG_LOCSET(set->ctx, node, NULL, NULL, NULL);
             LY_ARRAY_FOR(node->when, u) {
                 when = node->when[u];
                 ret = lyxp_atomize(when->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when->prefixes, when->context,
                         &tmp_set, LYXP_SCNODE_SCHEMA);
                 if (ret != LY_SUCCESS) {
-                    LOGVAL(set->ctx, LY_VLOG_LYSC, node, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when->cond->expr);
+                    LOGVAL(set->ctx, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when->cond->expr);
                     goto cleanup;
                 }
 
@@ -803,7 +812,7 @@
                         uint32_t idx;
                         if (lyxp_set_scnode_contains(set, tmp_set.val.scnodes[j].scnode, LYXP_NODE_ELEM, -1, &idx) &&
                                 (set->val.scnodes[idx].in_ctx == LYXP_SET_SCNODE_START_USED)) {
-                            LOGVAL(set->ctx, LY_VLOG_LYSC, node, LY_VCODE_CIRC_WHEN, node->name, set->val.scnodes[idx].scnode->name);
+                            LOGVAL(set->ctx, LYVE_SEMANTICS, "When condition includes a self-reference.");
                             ret = LY_EVALID;
                             goto cleanup;
                         }
@@ -822,6 +831,8 @@
 
             /* check when of non-data parents as well */
             node = node->parent;
+
+            LOG_LOCBACK(set->ctx, 1, 0, 0, 0);
         } while (node && (node->nodetype & (LYS_CASE | LYS_CHOICE)));
 
         /* this node when was checked (xp_scnode could have been reallocd) */
@@ -844,7 +855,7 @@
 
     if ((flg1 < flg2) && (mod1 == mod2)) {
         if (ctx) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "A %s definition \"%s\" is not allowed to reference %s definition \"%s\".",
                     flg1 == LYS_STATUS_CURR ? "current" : "deprecated", name1,
                     flg2 == LYS_STATUS_OBSLT ? "obsolete" : "deprecated", name2);
@@ -917,6 +928,8 @@
     const struct lysc_node *op;
     const struct lys_module *mod;
 
+    LOG_LOCSET(ctx->ctx, node, NULL, NULL, NULL);
+
     memset(&tmp_set, 0, sizeof tmp_set);
     opts = LYXP_SCNODE_SCHEMA;
     if (node->flags & LYS_CONFIG_R) {
@@ -987,7 +1000,7 @@
         ret = lyxp_atomize(when[u]->cond, node->module, LY_PREF_SCHEMA_RESOLVED, when[u]->prefixes, when[u]->context,
                 &tmp_set, opts);
         if (ret) {
-            LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when[u]->cond->expr);
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid when condition \"%s\".", when[u]->cond->expr);
             goto cleanup;
         }
 
@@ -1005,7 +1018,7 @@
 
                 /* check dummy node accessing */
                 if (schema == node) {
-                    LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LY_VCODE_DUMMY_WHEN, node->name);
+                    LOGVAL(ctx->ctx, LYVE_SEMANTICS, "When condition is accessing its own conditional node.");
                     ret = LY_EVALID;
                     goto cleanup;
                 }
@@ -1036,7 +1049,7 @@
         /* check "must" */
         ret = lyxp_atomize(musts[u].cond, node->module, LY_PREF_SCHEMA_RESOLVED, musts[u].prefixes, node, &tmp_set, opts);
         if (ret) {
-            LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_SEMANTICS, "Invalid must restriction \"%s\".", musts[u].cond->expr);
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid must restriction \"%s\".", musts[u].cond->expr);
             goto cleanup;
         }
 
@@ -1066,6 +1079,7 @@
 
 cleanup:
     lyxp_set_free_content(&tmp_set);
+    LOG_LOCBACK(ctx->ctx, 1, 0, 0, 0);
     return ret;
 }
 
@@ -1098,8 +1112,7 @@
     ly_path_free(node->module->ctx, p);
 
     if (!(target->nodetype & (LYS_LEAF | LYS_LEAFLIST))) {
-        LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_REFERENCE,
-                "Invalid leafref path \"%s\" - target node is %s instead of leaf or leaf-list.",
+        LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid leafref path \"%s\" - target node is %s instead of leaf or leaf-list.",
                 lref->path->expr, lys_nodetype2str(target->nodetype));
         return LY_EVALID;
     }
@@ -1118,7 +1131,7 @@
     if (lref->require_instance) {
         for (siter = node->parent; siter && !(siter->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)); siter = siter->parent) {}
         if (!siter && (node->flags & LYS_CONFIG_W) && (target->flags & LYS_CONFIG_R)) {
-            LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_REFERENCE, "Invalid leafref path \"%s\" - target is supposed"
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid leafref path \"%s\" - target is supposed"
                     " to represent configuration data (as the leafref does), but it does not.", lref->path->expr);
             return LY_EVALID;
         }
@@ -1129,8 +1142,8 @@
     for (type = lref->realtype; type && type->basetype == LY_TYPE_LEAFREF; type = ((struct lysc_type_leafref *)type)->realtype) {
         if (type == (struct lysc_type *)lref) {
             /* circular chain detected */
-            LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_REFERENCE,
-                    "Invalid leafref path \"%s\" - circular chain of leafrefs detected.", lref->path->expr);
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid leafref path \"%s\" - circular chain of leafrefs detected.",
+                    lref->path->expr);
             return LY_EVALID;
         }
     }
@@ -1169,15 +1182,14 @@
     }
 
     if (ret) {
-        ctx->path[0] = '\0';
-        lysc_path(node, LYSC_PATH_LOG, ctx->path, LYSC_CTX_BUFSIZE);
+        LOG_LOCSET(ctx->ctx, node, NULL, NULL, NULL);
         if (err) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                    "Invalid default - value does not fit the type (%s).", err->msg);
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid default - value does not fit the type (%s).", err->msg);
             ly_err_free(err);
         } else {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "Invalid default - value does not fit the type.");
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid default - value does not fit the type.");
         }
+        LOG_LOCBACK(ctx->ctx, 1, 0, 0, 0);
         return ret;
     }
 
@@ -1270,8 +1282,7 @@
             for (v = 0; v < u; ++v) {
                 if (!llist->dflts[u]->realtype->plugin->compare(llist->dflts[u], llist->dflts[v])) {
                     lysc_update_path(ctx, llist->parent, llist->name);
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                            "Configuration leaf-list has multiple defaults of the same value \"%s\".",
+                    LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Configuration leaf-list has multiple defaults of the same value \"%s\".",
                             llist->dflts[u]->canonical);
                     lysc_update_path(ctx, NULL, NULL);
                     return LY_EVALID;
@@ -1286,6 +1297,7 @@
 LY_ERR
 lys_compile_unres_glob(struct ly_ctx *ctx, struct lys_glob_unres *unres)
 {
+    LY_ERR ret;
     struct lysc_node *node;
     struct lysc_type *type, *typeiter;
     struct lysc_type_leafref *lref;
@@ -1308,28 +1320,41 @@
      * can be also leafref, in case it is already resolved, go through the chain and check that it does not
      * point to the starting leafref type). The second round stores the first non-leafref type for later data validation. */
     for (i = 0; i < unres->leafrefs.count; ++i) {
+        LY_ERR ret = LY_SUCCESS;
         node = unres->leafrefs.objs[i];
         cctx.cur_mod = node->module;
         cctx.pmod = node->module->parsed;
 
+        LOG_LOCSET(ctx, node, NULL, NULL, NULL);
+
         assert(node->nodetype & (LYS_LEAF | LYS_LEAFLIST));
         type = ((struct lysc_node_leaf *)node)->type;
         if (type->basetype == LY_TYPE_LEAFREF) {
-            LY_CHECK_RET(lys_compile_unres_leafref(&cctx, node, (struct lysc_type_leafref *)type, unres));
+            ret = lys_compile_unres_leafref(&cctx, node, (struct lysc_type_leafref *)type, unres);
         } else if (type->basetype == LY_TYPE_UNION) {
             LY_ARRAY_FOR(((struct lysc_type_union *)type)->types, v) {
                 if (((struct lysc_type_union *)type)->types[v]->basetype == LY_TYPE_LEAFREF) {
                     lref = (struct lysc_type_leafref *)((struct lysc_type_union *)type)->types[v];
-                    LY_CHECK_RET(lys_compile_unres_leafref(&cctx, node, lref, unres));
+                    ret = lys_compile_unres_leafref(&cctx, node, lref, unres);
+                    if (ret) {
+                        break;
+                    }
                 }
             }
         }
+
+        LOG_LOCBACK(ctx, 1, 0, 0, 0);
+        if (ret) {
+            return ret;
+        }
     }
     while (unres->leafrefs.count) {
         node = unres->leafrefs.objs[unres->leafrefs.count - 1];
         cctx.cur_mod = node->module;
         cctx.pmod = node->module->parsed;
 
+        LOG_LOCSET(ctx, node, NULL, NULL, NULL);
+
         /* store pointer to the real type */
         type = ((struct lysc_node_leaf *)node)->type;
         if (type->basetype == LY_TYPE_LEAFREF) {
@@ -1347,6 +1372,7 @@
                 }
             }
         }
+        LOG_LOCBACK(ctx, 1, 0, 0, 0);
 
         ly_set_rm_index(&unres->leafrefs, unres->leafrefs.count - 1, NULL);
     }
@@ -1357,7 +1383,11 @@
         cctx.cur_mod = node->module;
         cctx.pmod = node->module->parsed;
 
-        LY_CHECK_RET(lys_compile_unres_xpath(&cctx, node, unres));
+        LOG_LOCSET(ctx, node, NULL, NULL, NULL);
+
+        ret = lys_compile_unres_xpath(&cctx, node, unres);
+        LOG_LOCBACK(ctx, 1, 0, 0, 0);
+        LY_CHECK_RET(ret);
 
         ly_set_rm_index(&unres->xpath, unres->xpath.count - 1, NULL);
     }
@@ -1368,13 +1398,17 @@
         cctx.cur_mod = r->leaf->module;
         cctx.pmod = r->leaf->module->parsed;
 
-        if (r->leaf->nodetype == LYS_LEAF) {
-            LY_CHECK_RET(lys_compile_unres_leaf_dlft(&cctx, r->leaf, r->dflt, unres));
-        } else {
-            LY_CHECK_RET(lys_compile_unres_llist_dflts(&cctx, r->llist, r->dflt, r->dflts, unres));
-        }
-        lysc_unres_dflt_free(ctx, r);
+        LOG_LOCSET(ctx, (struct lysc_node *)r->leaf, NULL, NULL, NULL);
 
+        if (r->leaf->nodetype == LYS_LEAF) {
+            ret = lys_compile_unres_leaf_dlft(&cctx, r->leaf, r->dflt, unres);
+        } else {
+            ret = lys_compile_unres_llist_dflts(&cctx, r->llist, r->dflt, r->dflts, unres);
+        }
+        LOG_LOCBACK(ctx, 1, 0, 0, 0);
+        LY_CHECK_RET(ret);
+
+        lysc_unres_dflt_free(ctx, r);
         ly_set_rm_index(&unres->dflts, unres->dflts.count - 1, NULL);
     }
 
@@ -1469,8 +1503,9 @@
     for (i = 0; i < ctx->disabled.count; ++i) {
         node = ctx->disabled.snodes[i];
         if (node->flags & LYS_KEY) {
-            LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_REFERENCE, "Key \"%s\" is disabled by its if-features.",
-                    node->name);
+            LOG_LOCSET(ctx->ctx, node, NULL, NULL, NULL);
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Key \"%s\" is disabled by its if-features.", node->name);
+            LOG_LOCBACK(ctx->ctx, 1, 0, 0, 0);
             return LY_EVALID;
         }
 
@@ -1518,9 +1553,12 @@
     /* check that all augments were applied */
     for (i = 0; i < ctx->augs.count; ++i) {
         aug = ctx->augs.objs[i];
-        LOGVAL(ctx->ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE,
-                "Augment target node \"%s\" from module \"%s\" was not found.", aug->nodeid->expr,
-                LYSP_MODULE_NAME(aug->nodeid_pmod));
+        lysc_update_path(ctx, NULL, "{augment}");
+        lysc_update_path(ctx, NULL, aug->nodeid->expr);
+        LOGVAL(ctx->ctx, LYVE_REFERENCE, "Augment target node \"%s\" from module \"%s\" was not found.",
+                aug->nodeid->expr, LYSP_MODULE_NAME(aug->nodeid_pmod));
+        lysc_update_path(ctx, NULL, NULL);
+        lysc_update_path(ctx, NULL, NULL);
     }
     if (ctx->augs.count) {
         return LY_ENOTFOUND;
@@ -1529,9 +1567,12 @@
     /* check that all deviations were applied */
     for (i = 0; i < ctx->devs.count; ++i) {
         dev = ctx->devs.objs[i];
-        LOGVAL(ctx->ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE,
-                "Deviation(s) target node \"%s\" from module \"%s\" was not found.", dev->nodeid->expr,
-                LYSP_MODULE_NAME(dev->dev_pmods[0]));
+        lysc_update_path(ctx, NULL, "{deviation}");
+        lysc_update_path(ctx, NULL, dev->nodeid->expr);
+        LOGVAL(ctx->ctx, LYVE_REFERENCE, "Deviation(s) target node \"%s\" from module \"%s\" was not found.",
+                dev->nodeid->expr, LYSP_MODULE_NAME(dev->dev_pmods[0]));
+        lysc_update_path(ctx, NULL, NULL);
+        lysc_update_path(ctx, NULL, NULL);
     }
     if (ctx->devs.count) {
         return LY_ENOTFOUND;
@@ -1796,6 +1837,8 @@
     }
     ctx.pmod = sp;
 
+    LOG_LOCBACK(ctx.ctx, 0, 0, 1, 0);
+
     /* finish compilation for all unresolved module items in the context */
     LY_CHECK_GOTO(ret = lys_compile_unres_mod(&ctx), error);
 
@@ -1803,6 +1846,7 @@
     return LY_SUCCESS;
 
 error:
+    LOG_LOCBACK(ctx.ctx, 0, 0, 1, 0);
     lys_precompile_augments_deviations_revert(ctx.ctx, mod);
     lys_compile_unres_mod_erase(&ctx, 1);
     lysc_module_free(mod_c, NULL);
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 8093d86..7c56022 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -51,7 +51,7 @@
     /* parse */
     ret = lyxp_expr_parse(ctx->ctx, nodeid, strlen(nodeid), 0, &e);
     if (ret) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid %s value \"%s\" - invalid syntax.",
+        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Invalid %s value \"%s\" - invalid syntax.",
                 nodeid_type, nodeid);
         ret = LY_EVALID;
         goto cleanup;
@@ -63,7 +63,7 @@
     } else {
         /* descendant schema nodeid */
         if (e->tokens[0] != LYXP_TOKEN_NAMETEST) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "Invalid %s value \"%s\" - name test expected instead of \"%.*s\".",
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid %s value \"%s\" - name test expected instead of \"%.*s\".",
                     nodeid_type, nodeid, e->tok_len[0], e->expr + e->tok_pos[0]);
             ret = LY_EVALID;
             goto cleanup;
@@ -74,17 +74,17 @@
     /* check all the tokens */
     for ( ; i < e->used; i += 2) {
         if (e->tokens[i] != LYXP_TOKEN_OPER_PATH) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "Invalid %s value \"%s\" - \"/\" expected instead of \"%.*s\".",
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid %s value \"%s\" - \"/\" expected instead of \"%.*s\".",
                     nodeid_type, nodeid, e->tok_len[i], e->expr + e->tok_pos[i]);
             ret = LY_EVALID;
             goto cleanup;
         } else if (e->used == i + 1) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid %s value \"%s\" - unexpected end of expression.", nodeid_type, e->expr);
             ret = LY_EVALID;
             goto cleanup;
         } else if (e->tokens[i + 1] != LYXP_TOKEN_NAMETEST) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "Invalid %s value \"%s\" - name test expected instead of \"%.*s\".",
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid %s value \"%s\" - name test expected instead of \"%.*s\".",
                     nodeid_type, nodeid, e->tok_len[i + 1], e->expr + e->tok_pos[i + 1]);
             ret = LY_EVALID;
             goto cleanup;
@@ -652,14 +652,14 @@
 }
 
 #define AMEND_WRONG_NODETYPE(AMEND_STR, OP_STR, PROPERTY) \
-    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "Invalid %s of %s node - it is not possible to %s \"%s\" property.", \
+    LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid %s of %s node - it is not possible to %s \"%s\" property.", \
             AMEND_STR, lys_nodetype2str(target->nodetype), OP_STR, PROPERTY);\
     ret = LY_EVALID; \
     goto cleanup;
 
 #define AMEND_CHECK_CARDINALITY(ARRAY, MAX, AMEND_STR, PROPERTY) \
     if (LY_ARRAY_COUNT(ARRAY) > MAX) { \
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "Invalid %s of %s with too many (%"LY_PRI_ARRAY_COUNT_TYPE") %s properties.", \
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid %s of %s with too many (%"LY_PRI_ARRAY_COUNT_TYPE") %s properties.", \
                AMEND_STR, lys_nodetype2str(target->nodetype), LY_ARRAY_COUNT(ARRAY), PROPERTY); \
         ret = LY_EVALID; \
         goto cleanup; \
@@ -693,7 +693,7 @@
             break;
         case LYS_LEAFLIST:
             if (rfn->dflts[0].mod->version < LYS_VERSION_1_1) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                         "Invalid refine of default in leaf-list - the default statement is allowed only in YANG 1.1 modules.");
                 ret = LY_EVALID;
                 goto cleanup;
@@ -870,8 +870,7 @@
 
 #define DEV_CHECK_NONPRESENCE(TYPE, MEMBER, PROPERTY, VALUEMEMBER) \
     if (((TYPE)target)->MEMBER) { \
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, \
-                "Invalid deviation adding \"%s\" property which already exists (with value \"%s\").", \
+        LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid deviation adding \"%s\" property which already exists (with value \"%s\").", \
                 PROPERTY, ((TYPE)target)->VALUEMEMBER); \
         ret = LY_EVALID; \
         goto cleanup; \
@@ -976,7 +975,7 @@
         }
 
         if (target->flags & LYS_CONFIG_MASK) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid deviation adding \"config\" property which already exists (with value \"config %s\").",
                     target->flags & LYS_CONFIG_W ? "true" : "false");
             ret = LY_EVALID;
@@ -999,7 +998,7 @@
         }
 
         if (target->flags & LYS_MAND_MASK) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid deviation adding \"mandatory\" property which already exists (with value \"mandatory %s\").",
                     target->flags & LYS_MAND_TRUE ? "true" : "false");
             ret = LY_EVALID;
@@ -1023,7 +1022,7 @@
         }
 
         if (target->flags & LYS_SET_MIN) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid deviation adding \"min-elements\" property which already exists (with value \"%u\").", *num);
             ret = LY_EVALID;
             goto cleanup;
@@ -1047,11 +1046,11 @@
 
         if (target->flags & LYS_SET_MAX) {
             if (*num) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                LOGVAL(ctx->ctx, LYVE_REFERENCE,
                         "Invalid deviation adding \"max-elements\" property which already exists (with value \"%u\").",
                         *num);
             } else {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                LOGVAL(ctx->ctx, LYVE_REFERENCE,
                         "Invalid deviation adding \"max-elements\" property which already exists (with value \"unbounded\").");
             }
             ret = LY_EVALID;
@@ -1091,7 +1090,7 @@
             } \
         } \
         if (!found) { \
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, \
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, \
                     "Invalid deviation deleting \"%s\" property \"%s\" which does not match any of the target's property values.", \
                     PROPERTY, d->DEV_ARRAY[u]DEV_MEMBER); \
             ret = LY_EVALID; \
@@ -1108,11 +1107,11 @@
 
 #define DEV_CHECK_PRESENCE_VALUE(TYPE, MEMBER, DEVTYPE, PROPERTY, VALUE) \
     if (!((TYPE)target)->MEMBER) { \
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_DEV_NOT_PRESENT, DEVTYPE, PROPERTY, VALUE); \
+        LOGVAL(ctx->ctx, LY_VCODE_DEV_NOT_PRESENT, DEVTYPE, PROPERTY, VALUE); \
         ret = LY_EVALID; \
         goto cleanup; \
     } else if (strcmp(((TYPE)target)->MEMBER, VALUE)) { \
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, \
+        LOGVAL(ctx->ctx, LYVE_REFERENCE, \
                 "Invalid deviation deleting \"%s\" property \"%s\" which does not match the target's property value \"%s\".", \
                 PROPERTY, VALUE, ((TYPE)target)->MEMBER); \
         ret = LY_EVALID; \
@@ -1218,7 +1217,7 @@
 
 #define DEV_CHECK_PRESENCE(TYPE, MEMBER, DEVTYPE, PROPERTY, VALUE) \
     if (!((TYPE)target)->MEMBER) { \
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_DEV_NOT_PRESENT, DEVTYPE, PROPERTY, VALUE); \
+        LOGVAL(ctx->ctx, LY_VCODE_DEV_NOT_PRESENT, DEVTYPE, PROPERTY, VALUE); \
         ret = LY_EVALID; \
         goto cleanup; \
     }
@@ -1288,8 +1287,8 @@
         }
 
         if (!(target->flags & LYS_CONFIG_MASK)) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_DEV_NOT_PRESENT,
-                    "replacing", "config", d->flags & LYS_CONFIG_W ? "config true" : "config false");
+            LOGVAL(ctx->ctx, LY_VCODE_DEV_NOT_PRESENT, "replacing", "config",
+                    d->flags & LYS_CONFIG_W ? "config true" : "config false");
             ret = LY_EVALID;
             goto cleanup;
         }
@@ -1311,8 +1310,8 @@
         }
 
         if (!(target->flags & LYS_MAND_MASK)) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_DEV_NOT_PRESENT,
-                    "replacing", "mandatory", d->flags & LYS_MAND_TRUE ? "mandatory true" : "mandatory false");
+            LOGVAL(ctx->ctx, LY_VCODE_DEV_NOT_PRESENT, "replacing", "mandatory",
+                    d->flags & LYS_MAND_TRUE ? "mandatory true" : "mandatory false");
             ret = LY_EVALID;
             goto cleanup;
         }
@@ -1335,8 +1334,7 @@
         }
 
         if (!(target->flags & LYS_SET_MIN)) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
-                    "Invalid deviation replacing \"min-elements\" property which is not present.");
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid deviation replacing \"min-elements\" property which is not present.");
             ret = LY_EVALID;
             goto cleanup;
         }
@@ -1358,8 +1356,7 @@
         }
 
         if (!(target->flags & LYS_SET_MAX)) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
-                    "Invalid deviation replacing \"max-elements\" property which is not present.");
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid deviation replacing \"max-elements\" property which is not present.");
             ret = LY_EVALID;
             goto cleanup;
         }
@@ -1393,7 +1390,7 @@
     if (ptr) {
         target_mod = ly_resolve_prefix(ctx, nametest, ptr - nametest, LY_PREF_SCHEMA, (void *)mod);
         if (!target_mod) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE,
+            LOGVAL(ctx, LYVE_REFERENCE,
                     "Invalid absolute-schema-nodeid nametest \"%.*s\" - prefix \"%.*s\" not defined in module \"%s\".",
                     nametest_len, nametest, ptr - nametest, nametest, LYSP_MODULE_NAME(mod));
             return NULL;
@@ -1802,7 +1799,7 @@
     uint32_t i, opt_prev = ctx->options;
 
     if (!(target->nodetype & (LYS_CONTAINER | LYS_LIST | LYS_CHOICE | LYS_CASE | LYS_INPUT | LYS_OUTPUT | LYS_NOTIF))) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+        LOGVAL(ctx->ctx, LYVE_REFERENCE,
                 "Augment's %s-schema-nodeid \"%s\" refers to a %s node which is not an allowed augment's target.",
                 aug_p->nodeid[0] == '/' ? "absolute" : "descendant", aug_p->nodeid, lys_nodetype2str(target->nodetype));
         ret = LY_EVALID;
@@ -1822,7 +1819,7 @@
         if (((pnode->nodetype == LYS_CASE) && (target->nodetype != LYS_CHOICE)) ||
                 ((pnode->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && !(target->nodetype & (LYS_CONTAINER | LYS_LIST))) ||
                 ((pnode->nodetype == LYS_USES) && (target->nodetype == LYS_CHOICE))) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid augment of %s node which is not allowed to contain %s node \"%s\".",
                     lys_nodetype2str(target->nodetype), lys_nodetype2str(pnode->nodetype), pnode->name);
             ret = LY_EVALID;
@@ -1857,7 +1854,7 @@
             if (!allow_mandatory && (node->flags & LYS_CONFIG_W) && (node->flags & LYS_MAND_TRUE)) {
                 node->flags &= ~LYS_MAND_TRUE;
                 lys_compile_mandatory_parents(target, 0);
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                         "Invalid augment adding mandatory node \"%s\" without making it conditional via when statement.", node->name);
                 ret = LY_EVALID;
                 goto cleanup;
@@ -1899,7 +1896,7 @@
 
     if (aug_p->actions) {
         if (!actions) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid augment of %s node which is not allowed to contain RPC/action node \"%s\".",
                     lys_nodetype2str(target->nodetype), aug_p->actions[0].name);
             ret = LY_EVALID;
@@ -1920,7 +1917,7 @@
     }
     if (aug_p->notifs) {
         if (!notifs) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid augment of %s node which is not allowed to contain notification node \"%s\".",
                     lys_nodetype2str(target->nodetype), aug_p->notifs[0].name);
             ret = LY_EVALID;
@@ -2184,7 +2181,7 @@
             }
         }
         if (not_supported && (LY_ARRAY_COUNT(dev->devs) > 1)) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                     "Multiple deviations of \"%s\" with one of them being \"not-supported\".", dev->nodeid->expr);
             return LY_EVALID;
         }
diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c
index cac24e9..93b15ab 100644
--- a/src/schema_compile_node.c
+++ b/src/schema_compile_node.c
@@ -376,7 +376,7 @@
 decimal:
         assert(frdigits);
         if (fraction && (*len - 1 - fraction > frdigits)) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+            LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                     "Range boundary \"%.*s\" of decimal64 type exceeds defined number (%u) of fraction digits.",
                     *len, value, frdigits);
             return LY_EINVAL;
@@ -578,15 +578,15 @@
 
 finalize:
     if (ret == LY_EDENIED) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                 "Invalid %s restriction - value \"%s\" does not fit the type limitations.",
                 length_restr ? "length" : "range", valcopy ? valcopy : *value);
     } else if (ret == LY_EVALID) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                 "Invalid %s restriction - invalid value \"%s\".",
                 length_restr ? "length" : "range", valcopy ? valcopy : *value);
     } else if (ret == LY_EEXIST) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                 "Invalid %s restriction - values are not in ascending order (%s).",
                 length_restr ? "length" : "range",
                 (valcopy && basetype != LY_TYPE_DEC64) ? valcopy : value ? *value : max ? "max" : "min");
@@ -628,12 +628,12 @@
             ++expr;
         } else if (*expr == '\0') {
             if (range_expected) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Invalid %s restriction - unexpected end of the expression after \"..\" (%s).",
                         length_restr ? "length" : "range", range_p->arg);
                 goto cleanup;
             } else if (!parts || (parts_done == LY_ARRAY_COUNT(parts))) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Invalid %s restriction - unexpected end of the expression (%s).",
                         length_restr ? "length" : "range", range_p->arg);
                 goto cleanup;
@@ -643,7 +643,7 @@
         } else if (!strncmp(expr, "min", ly_strlen_const("min"))) {
             if (parts) {
                 /* min cannot be used elsewhere than in the first part */
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Invalid %s restriction - unexpected data before min keyword (%.*s).", length_restr ? "length" : "range",
                         expr - range_p->arg.str, range_p->arg.str);
                 goto cleanup;
@@ -655,7 +655,7 @@
             part->max_64 = part->min_64;
         } else if (*expr == '|') {
             if (!parts || range_expected) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Invalid %s restriction - unexpected beginning of the expression (%s).", length_restr ? "length" : "range", expr);
                 goto cleanup;
             }
@@ -668,7 +668,7 @@
                 expr++;
             }
             if (!parts || (LY_ARRAY_COUNT(parts) == parts_done)) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Invalid %s restriction - unexpected \"..\" without a lower bound.", length_restr ? "length" : "range");
                 goto cleanup;
             }
@@ -694,7 +694,7 @@
                 expr++;
             }
             if (*expr != '\0') {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid %s restriction - unexpected data after max keyword (%s).",
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Invalid %s restriction - unexpected data after max keyword (%s).",
                         length_restr ? "length" : "range", expr);
                 goto cleanup;
             }
@@ -709,7 +709,7 @@
                 part->min_64 = part->max_64;
             }
         } else {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid %s restriction - unexpected data (%s).",
+            LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Invalid %s restriction - unexpected data (%s).",
                     length_restr ? "length" : "range", expr);
             goto cleanup;
         }
@@ -797,7 +797,7 @@
         }
         if (u != parts_done) {
 baseerror:
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+            LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                     "Invalid %s restriction - the derived restriction (%s) is not equally or more limiting.",
                     length_restr ? "length" : "range", range_p->arg);
             goto cleanup;
@@ -838,7 +838,7 @@
 }
 
 LY_ERR
-lys_compile_type_pattern_check(struct ly_ctx *ctx, const char *log_path, const char *pattern, pcre2_code **code)
+lys_compile_type_pattern_check(struct ly_ctx *ctx, const char *pattern, pcre2_code **code)
 {
     size_t idx, idx2, start, end, size, brack;
     char *perl_regex, *ptr;
@@ -995,8 +995,7 @@
 
         ptr = strchr(ptr, '}');
         if (!ptr) {
-            LOGVAL(ctx, LY_VLOG_STR, log_path, LY_VCODE_INREGEXP,
-                    pattern, perl_regex + start + 2, "unterminated character property");
+            LOGVAL(ctx, LY_VCODE_INREGEXP, pattern, perl_regex + start + 2, "unterminated character property");
             free(perl_regex);
             return LY_EVALID;
         }
@@ -1016,8 +1015,7 @@
             }
         }
         if (!ublock2urange[idx][0]) {
-            LOGVAL(ctx, LY_VLOG_STR, log_path, LY_VCODE_INREGEXP,
-                    pattern, perl_regex + start + 5, "unknown block name");
+            LOGVAL(ctx, LY_VCODE_INREGEXP, pattern, perl_regex + start + 5, "unknown block name");
             free(perl_regex);
             return LY_EVALID;
         }
@@ -1048,7 +1046,7 @@
     if (!code_local) {
         PCRE2_UCHAR err_msg[LY_PCRE2_MSG_LIMIT] = {0};
         pcre2_get_error_message(err_code, err_msg, LY_PCRE2_MSG_LIMIT);
-        LOGVAL(ctx, LY_VLOG_STR, log_path, LY_VCODE_INREGEXP, pattern, perl_regex + err_offset, err_msg);
+        LOGVAL(ctx, LY_VCODE_INREGEXP, pattern, perl_regex + err_offset, err_msg);
         free(perl_regex);
         return LY_EVALID;
     }
@@ -1093,7 +1091,7 @@
         *pattern = calloc(1, sizeof **pattern);
         ++(*pattern)->refcount;
 
-        ret = lys_compile_type_pattern_check(ctx->ctx, ctx->path, &patterns_p[u].arg.str[1], &(*pattern)->code);
+        ret = lys_compile_type_pattern_check(ctx->ctx, &patterns_p[u].arg.str[1], &(*pattern)->code);
         LY_CHECK_RET(ret);
 
         if (patterns_p[u].arg.str[0] == LYSP_RESTR_PATTERN_NACK) {
@@ -1166,7 +1164,7 @@
     ly_bool enabled;
 
     if (base_enums && (ctx->pmod->version < LYS_VERSION_1_1)) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "%s type can be subtyped only in YANG 1.1 modules.",
+        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "%s type can be subtyped only in YANG 1.1 modules.",
                 basetype == LY_TYPE_ENUM ? "Enumeration" : "Bits");
         return LY_EVALID;
     }
@@ -1181,7 +1179,7 @@
                 }
             }
             if (v == LY_ARRAY_COUNT(base_enums)) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                         "Invalid %s - derived type adds new item \"%s\".",
                         basetype == LY_TYPE_ENUM ? "enumeration" : "bits", enums_p[u].name);
                 return LY_EVALID;
@@ -1196,7 +1194,7 @@
                 /* check collision with other values */
                 LY_ARRAY_FOR(*enums, v) {
                     if (cur_val == (*enums)[v].value) {
-                        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                                 "Invalid enumeration - value %d collide in items \"%s\" and \"%s\".",
                                 cur_val, enums_p[u].name, (*enums)[v].name);
                         return LY_EVALID;
@@ -1210,7 +1208,7 @@
                 if (u == 0) {
                     cur_val = 0;
                 } else if (highest_value == INT32_MAX) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid enumeration - it is not possible to auto-assign enum value for "
                             "\"%s\" since the highest value is already 2147483647.", enums_p[u].name);
                     return LY_EVALID;
@@ -1230,7 +1228,7 @@
                 /* check collision with other values */
                 LY_ARRAY_FOR(*enums, v) {
                     if (cur_pos == (*enums)[v].position) {
-                        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                                 "Invalid bits - position %u collide in items \"%s\" and \"%s\".",
                                 cur_pos, enums_p[u].name, (*enums)[v].name);
                         return LY_EVALID;
@@ -1245,7 +1243,7 @@
                     cur_pos = 0;
                 } else if (highest_position == UINT32_MAX) {
                     /* counter overflow */
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid bits - it is not possible to auto-assign bit position for "
                             "\"%s\" since the highest value is already 4294967295.", enums_p[u].name);
                     return LY_EVALID;
@@ -1264,14 +1262,14 @@
         if (base_enums) {
             if (basetype == LY_TYPE_ENUM) {
                 if (cur_val != base_enums[match].value) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid enumeration - value of the item \"%s\" has changed from %d to %d in the derived type.",
                             enums_p[u].name, base_enums[match].value, cur_val);
                     return LY_EVALID;
                 }
             } else {
                 if (cur_pos != base_enums[match].position) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid bits - position of the item \"%s\" has changed from %u to %u in the derived type.",
                             enums_p[u].name, base_enums[match].position, cur_pos);
                     return LY_EVALID;
@@ -1436,9 +1434,9 @@
         if (!base && !type_p->flags) {
             /* type derived from bits built-in type must contain at least one bit */
             if (tpdfname) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "bit", "bits type ", tpdfname);
+                LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "bit", "bits type ", tpdfname);
             } else {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "bit", "bits type", "");
+                LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "bit", "bits type", "");
             }
             return LY_EVALID;
         }
@@ -1450,9 +1448,9 @@
         if (!base) {
             if (!type_p->fraction_digits) {
                 if (tpdfname) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "fraction-digits", "decimal64 type ", tpdfname);
+                    LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "fraction-digits", "decimal64 type ", tpdfname);
                 } else {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "fraction-digits", "decimal64 type", "");
+                    LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "fraction-digits", "decimal64 type", "");
                 }
                 return LY_EVALID;
             }
@@ -1461,11 +1459,11 @@
             if (type_p->fraction_digits) {
                 /* fraction digits is prohibited in types not directly derived from built-in decimal64 */
                 if (tpdfname) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid fraction-digits substatement for type \"%s\" not directly derived from decimal64 built-in type.",
                             tpdfname);
                 } else {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid fraction-digits substatement for type not directly derived from decimal64 built-in type.");
                 }
                 return LY_EVALID;
@@ -1516,9 +1514,9 @@
         if (!base && !type_p->flags) {
             /* type derived from enumerations built-in type must contain at least one enum */
             if (tpdfname) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "enum", "enumeration type ", tpdfname);
+                LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "enum", "enumeration type ", tpdfname);
             } else {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "enum", "enumeration type", "");
+                LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "enum", "enumeration type", "");
             }
             return LY_EVALID;
         }
@@ -1550,11 +1548,11 @@
             if (base) {
                 /* only the directly derived identityrefs can contain base specification */
                 if (tpdfname) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid base substatement for the type \"%s\" not directly derived from identityref built-in type.",
                             tpdfname);
                 } else {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid base substatement for the type not directly derived from identityref built-in type.");
                 }
                 return LY_EVALID;
@@ -1565,9 +1563,9 @@
         if (!base && !type_p->flags) {
             /* type derived from identityref built-in type must contain at least one base */
             if (tpdfname) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "base", "identityref type ", tpdfname);
+                LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "base", "identityref type ", tpdfname);
             } else {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "base", "identityref type", "");
+                LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "base", "identityref type", "");
             }
             return LY_EVALID;
         }
@@ -1579,10 +1577,10 @@
         if (type_p->flags & LYS_SET_REQINST) {
             if (context_mod->version < LYS_VERSION_1_1) {
                 if (tpdfname) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                    LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                             "Leafref type \"%s\" can be restricted by require-instance statement only in YANG 1.1 modules.", tpdfname);
                 } else {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                    LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                             "Leafref type can be restricted by require-instance statement only in YANG 1.1 modules.");
                 }
                 return LY_EVALID;
@@ -1603,10 +1601,10 @@
             LY_CHECK_RET(lyxp_expr_dup(ctx->ctx, ((struct lysc_type_leafref *)base)->path, &lref->path));
             LY_CHECK_RET(lysc_prefixes_dup(((struct lysc_type_leafref *)base)->prefixes, &lref->prefixes));
         } else if (tpdfname) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "path", "leafref type ", tpdfname);
+            LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "path", "leafref type ", tpdfname);
             return LY_EVALID;
         } else {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "path", "leafref type", "");
+            LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "path", "leafref type", "");
             return LY_EVALID;
         }
         lref->cur_mod = type_p->pmod->mod;
@@ -1628,11 +1626,11 @@
             if (base) {
                 /* only the directly derived union can contain types specification */
                 if (tpdfname) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid type substatement for the type \"%s\" not directly derived from union built-in type.",
                             tpdfname);
                 } else {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG,
                             "Invalid type substatement for the type not directly derived from union built-in type.");
                 }
                 return LY_EVALID;
@@ -1645,9 +1643,9 @@
         if (!base && !type_p->flags) {
             /* type derived from union built-in type must contain at least one type */
             if (tpdfname) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "type", "union type ", tpdfname);
+                LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "type", "union type ", tpdfname);
             } else {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_MISSCHILDSTMT, "type", "union type", "");
+                LOGVAL(ctx->ctx, LY_VCODE_MISSCHILDSTMT, "type", "union type", "");
             }
             return LY_EVALID;
         }
@@ -1790,7 +1788,7 @@
             /* local part */
             tctx_iter = (struct type_context *)tpdf_chain.objs[u];
             if ((tctx_iter->mod == tctx->mod) && (tctx_iter->node == tctx->node) && (tctx_iter->tpdf == tctx->tpdf)) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                LOGVAL(ctx->ctx, LYVE_REFERENCE,
                         "Invalid \"%s\" type reference - circular chain of types detected.", tctx->tpdf->name);
                 free(tctx);
                 ret = LY_EVALID;
@@ -1801,7 +1799,7 @@
             /* global part for unions corner case */
             tctx_iter = (struct type_context *)ctx->tpdf_chain.objs[u];
             if ((tctx_iter->mod == tctx->mod) && (tctx_iter->node == tctx->node) && (tctx_iter->tpdf == tctx->tpdf)) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                LOGVAL(ctx->ctx, LYVE_REFERENCE,
                         "Invalid \"%s\" type reference - circular chain of types detected.", tctx->tpdf->name);
                 free(tctx);
                 ret = LY_EVALID;
@@ -1865,14 +1863,14 @@
         *type = calloc(1, sizeof(struct lysc_type_num));
         break;
     case LY_TYPE_UNKNOWN:
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+        LOGVAL(ctx->ctx, LYVE_REFERENCE,
                 "Referenced type \"%s\" not found.", tctx_prev ? tctx_prev->tpdf->type.name : type_p->name);
         ret = LY_EVALID;
         goto cleanup;
     }
     LY_CHECK_ERR_GOTO(!(*type), LOGMEM(ctx->ctx), cleanup);
     if (~type_substmt_map[basetype] & type_p->flags) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid type restrictions for %s type.",
+        LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Invalid type restrictions for %s type.",
                 ly_data_type2str[basetype]);
         free(*type);
         (*type) = NULL;
@@ -1900,12 +1898,12 @@
 
         ++(*type)->refcount;
         if (~type_substmt_map[basetype] & tctx->tpdf->type.flags) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SYNTAX_YANG, "Invalid type \"%s\" restriction(s) for %s type.",
+            LOGVAL(ctx->ctx, LYVE_SYNTAX_YANG, "Invalid type \"%s\" restriction(s) for %s type.",
                     tctx->tpdf->name, ly_data_type2str[basetype]);
             ret = LY_EVALID;
             goto cleanup;
         } else if ((basetype == LY_TYPE_EMPTY) && tctx->tpdf->dflt.str) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                     "Invalid type \"%s\" - \"empty\" type must not have a default value (%s).",
                     tctx->tpdf->name, tctx->tpdf->dflt.str);
             ret = LY_EVALID;
@@ -1987,11 +1985,11 @@
         /* check status compatibility with the parent */
         if ((parent_flags & LYS_STATUS_MASK) > ((*node_flags) & LYS_STATUS_MASK)) {
             if ((*node_flags) & LYS_STATUS_CURR) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                         "A \"current\" status is in conflict with the parent's \"%s\" status.",
                         (parent_flags & LYS_STATUS_DEPRC) ? "deprecated" : "obsolete");
             } else { /* LYS_STATUS_DEPRC */
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                         "A \"deprecated\" status is in conflict with the parent's \"obsolete\" status.");
             }
             return LY_EVALID;
@@ -2029,7 +2027,7 @@
         assert(parent->nodetype == LYS_CHOICE);
         LY_LIST_FOR(lysc_node_children(parent, 0), iter) {
             if (CHECK_NODE(iter, exclude, name)) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_DUPIDENT, name, "case");
+                LOGVAL(ctx->ctx, LY_VCODE_DUPIDENT, name, "case");
                 return LY_EEXIST;
             }
         }
@@ -2083,7 +2081,7 @@
     return LY_SUCCESS;
 
 error:
-    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LY_VCODE_DUPIDENT, name, "data definition/RPC/action/notification");
+    LOGVAL(ctx->ctx, LY_VCODE_DUPIDENT, name, "data definition/RPC/action/notification");
     return LY_EEXIST;
 
 #undef CHECK_NODE
@@ -2119,7 +2117,7 @@
     LY_CHECK_GOTO(ret = lys_compile_node_uniqness(ctx, parent, action_p->name, (struct lysc_node *)action), cleanup);
 
     if (ctx->options & (LYS_COMPILE_RPC_MASK | LYS_COMPILE_NOTIFICATION)) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                 "Action \"%s\" is placed inside %s.", action_p->name,
                 ctx->options & LYS_COMPILE_RPC_MASK ? "another RPC/action" : "notification");
         ret = LY_EVALID;
@@ -2256,7 +2254,7 @@
     LY_CHECK_GOTO(ret = lys_compile_node_uniqness(ctx, parent, notif_p->name, (struct lysc_node *)notif), cleanup);
 
     if (ctx->options & (LYS_COMPILE_RPC_MASK | LYS_COMPILE_NOTIFICATION)) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                 "Notification \"%s\" is placed inside %s.", notif_p->name,
                 ctx->options & LYS_COMPILE_RPC_MASK ? "RPC/action" : "another notification");
         ret = LY_EVALID;
@@ -2408,7 +2406,7 @@
         }
     } else if (leaf->type->basetype == LY_TYPE_EMPTY) {
         if ((leaf->nodetype == LYS_LEAFLIST) && (ctx->pmod->version < LYS_VERSION_1_1)) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                     "Leaf-list of type \"empty\" is allowed only in YANG 1.1 modules.");
             return LY_EVALID;
         }
@@ -2455,7 +2453,7 @@
 
     /* checks */
     if ((leaf->flags & LYS_SET_DFLT) && (leaf->flags & LYS_MAND_TRUE)) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                 "Invalid mandatory leaf with a default value.");
         return LY_EVALID;
     }
@@ -2497,7 +2495,7 @@
     /* store/update default values */
     if (llist_p->dflts) {
         if (ctx->pmod->version < LYS_VERSION_1_1) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                     "Leaf-list default values are allowed only in YANG 1.1 modules.");
             return LY_EVALID;
         }
@@ -2514,13 +2512,12 @@
 
     /* checks */
     if ((llist->flags & LYS_SET_DFLT) && (llist->flags & LYS_MAND_TRUE)) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
-                "The default statement is present on leaf-list with a nonzero min-elements.");
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS, "The default statement is present on leaf-list with a nonzero min-elements.");
         return LY_EVALID;
     }
 
     if (llist->min > llist->max) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "Leaf-list min-elements %u is bigger than max-elements %u.",
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Leaf-list min-elements %u is bigger than max-elements %u.",
                 llist->min, llist->max);
         return LY_EVALID;
     }
@@ -2555,7 +2552,7 @@
         nodeid_type = "descendant";
 
         if (*id == '/') {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid descendant-schema-nodeid value \"%.*s\" - absolute-schema-nodeid used.",
                     nodeid_len ? nodeid_len : strlen(nodeid), nodeid);
             return LY_EVALID;
@@ -2565,7 +2562,7 @@
         nodeid_type = "absolute";
 
         if (*id != '/') {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid absolute-schema-nodeid value \"%.*s\" - missing starting \"/\".",
                     nodeid_len ? nodeid_len : strlen(nodeid), nodeid);
             return LY_EVALID;
@@ -2579,7 +2576,7 @@
             if (!mod) {
                 /* module must always be found */
                 assert(prefix);
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                LOGVAL(ctx->ctx, LYVE_REFERENCE,
                         "Invalid %s-schema-nodeid value \"%.*s\" - prefix \"%.*s\" not defined in module \"%s\".",
                         nodeid_type, id - nodeid, nodeid, prefix_len, prefix, LYSP_MODULE_NAME(ctx->pmod));
                 return LY_ENOTFOUND;
@@ -2607,7 +2604,7 @@
         if (ctx_node && (ctx_node->nodetype & (LYS_RPC | LYS_ACTION))) {
             /* move through input/output manually */
             if (mod != ctx_node->module) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                LOGVAL(ctx->ctx, LYVE_REFERENCE,
                         "Invalid %s-schema-nodeid value \"%.*s\" - target node not found.", nodeid_type, id - nodeid, nodeid);
                 return LY_ENOTFOUND;
             }
@@ -2626,7 +2623,7 @@
             getnext_extra_flag = 0;
         }
         if (!ctx_node) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid %s-schema-nodeid value \"%.*s\" - target node not found.", nodeid_type, id - nodeid, nodeid);
             return LY_ENOTFOUND;
         }
@@ -2644,7 +2641,7 @@
             break;
         }
         if (*id != '/') {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid %s-schema-nodeid value \"%.*s\" - missing \"/\" as node-identifier separator.",
                     nodeid_type, id - nodeid + 1, nodeid);
             return LY_EVALID;
@@ -2658,7 +2655,7 @@
             return LY_EDENIED;
         }
     } else {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+        LOGVAL(ctx->ctx, LYVE_REFERENCE,
                 "Invalid %s-schema-nodeid value \"%.*s\" - unexpected end of expression.",
                 nodeid_type, nodeid_len ? nodeid_len : strlen(nodeid), nodeid);
     }
@@ -2706,13 +2703,13 @@
                     LY_PREF_SCHEMA, (void *)uniques[v].mod, LYS_LEAF, (const struct lysc_node **)key, &flags);
             if (ret != LY_SUCCESS) {
                 if (ret == LY_EDENIED) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                    LOGVAL(ctx->ctx, LYVE_REFERENCE,
                             "Unique's descendant-schema-nodeid \"%.*s\" refers to %s node instead of a leaf.",
                             len, keystr, lys_nodetype2str((*key)->nodetype));
                 }
                 return LY_EVALID;
             } else if (flags) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+                LOGVAL(ctx->ctx, LYVE_REFERENCE,
                         "Unique's descendant-schema-nodeid \"%.*s\" refers into %s node.",
                         len, keystr, flags & LYS_COMPILE_NOTIFICATION ? "notification" : "RPC/action");
                 return LY_EVALID;
@@ -2721,7 +2718,7 @@
             /* all referenced leafs must be of the same config type */
             if ((config != -1) && ((((*key)->flags & LYS_CONFIG_W) && (config == 0)) ||
                     (((*key)->flags & LYS_CONFIG_R) && (config == 1)))) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                         "Unique statement \"%s\" refers to leaves with different config type.", uniques[v].str);
                 return LY_EVALID;
             } else if ((*key)->flags & LYS_CONFIG_W) {
@@ -2733,7 +2730,7 @@
             /* we forbid referencing nested lists because it is unspecified what instance of such a list to use */
             for (parent = (*key)->parent; parent != (struct lysc_node *)list; parent = parent->parent) {
                 if (parent->nodetype == LYS_LIST) {
-                    LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                    LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                             "Unique statement \"%s\" refers to a leaf in nested list \"%s\".", uniques[v].str, parent->name);
                     return LY_EVALID;
                 }
@@ -2792,7 +2789,7 @@
 
     /* keys */
     if ((list->flags & LYS_CONFIG_W) && (!list_p->key || !list_p->key[0])) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "Missing key in list representing configuration data.");
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Missing key in list representing configuration data.");
         return LY_EVALID;
     }
 
@@ -2816,33 +2813,33 @@
         /* key node must be present */
         key = (struct lysc_node_leaf *)lys_find_child(node, node->module, keystr, len, LYS_LEAF, LYS_GETNEXT_NOCHOICE);
         if (!key) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "The list's key \"%.*s\" not found.", len, keystr);
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "The list's key \"%.*s\" not found.", len, keystr);
             return LY_EVALID;
         }
         /* keys must be unique */
         if (key->flags & LYS_KEY) {
             /* the node was already marked as a key */
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "Duplicated key identifier \"%.*s\".", len, keystr);
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Duplicated key identifier \"%.*s\".", len, keystr);
             return LY_EVALID;
         }
 
         lysc_update_path(ctx, (struct lysc_node *)list, key->name);
         /* key must have the same config flag as the list itself */
         if ((list->flags & LYS_CONFIG_MASK) != (key->flags & LYS_CONFIG_MASK)) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "Key of the configuration list must not be status leaf.");
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Key of the configuration list must not be status leaf.");
             return LY_EVALID;
         }
         if (ctx->pmod->version < LYS_VERSION_1_1) {
             /* YANG 1.0 denies key to be of empty type */
             if (key->type->basetype == LY_TYPE_EMPTY) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                         "List's key cannot be of \"empty\" type until it is in YANG 1.1 module.");
                 return LY_EVALID;
             }
         } else {
             /* when and if-feature are illegal on list keys */
             if (key->when) {
-                LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+                LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                         "List's key must not have any \"when\" statement.");
                 return LY_EVALID;
             }
@@ -2916,7 +2913,7 @@
 
     /* checks */
     if (list->min > list->max) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "List min-elements %u is bigger than max-elements %u.",
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS, "List min-elements %u is bigger than max-elements %u.",
                 list->min, list->max);
         return LY_EVALID;
     }
@@ -2955,7 +2952,7 @@
     if (prefix) {
         mod = ly_resolve_prefix(ctx->ctx, prefix, prefix_len, LY_PREF_SCHEMA, (void *)dflt->mod);
         if (!mod) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "Default case prefix \"%.*s\" not found "
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Default case prefix \"%.*s\" not found "
                     "in imports of \"%s\".", prefix_len, prefix, LYSP_MODULE_NAME(dflt->mod));
             return LY_EVALID;
         }
@@ -2965,7 +2962,7 @@
 
     ch->dflt = (struct lysc_node_case *)lys_find_child(node, mod, name, 0, LYS_CASE, LYS_GETNEXT_WITHCASE);
     if (!ch->dflt) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                 "Default case \"%s\" not found.", dflt->str);
         return LY_EVALID;
     }
@@ -2976,14 +2973,14 @@
             break;
         }
         if (iter->flags & LYS_MAND_TRUE) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+            LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                     "Mandatory node \"%s\" under the default case \"%s\".", iter->name, dflt->str);
             return LY_EVALID;
         }
     }
 
     if (ch->flags & LYS_MAND_TRUE) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS, "Invalid mandatory choice with a default case.");
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS, "Invalid mandatory choice with a default case.");
         return LY_EVALID;
     }
 
@@ -3310,7 +3307,7 @@
         /* foreign module, find it first */
         mod = ly_resolve_prefix(ctx->ctx, prefix, prefix_len, LY_PREF_SCHEMA, ctx->pmod);
         if (!mod) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+            LOGVAL(ctx->ctx, LYVE_REFERENCE,
                     "Invalid prefix used for grouping reference.", uses_p->name);
             return LY_EVALID;
         }
@@ -3345,7 +3342,7 @@
         }
     }
     if (!found) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                 "Grouping \"%s\" referenced by a uses statement not found.", uses_p->name);
         return LY_EVALID;
     }
@@ -3394,7 +3391,7 @@
     LY_CHECK_RET(ly_set_add(&ctx->groupings, (void *)grp, 0, NULL));
     if (grp_stack_count == ctx->groupings.count) {
         /* the target grouping is already in the stack, so we are already inside it -> circular dependency */
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+        LOGVAL(ctx->ctx, LYVE_REFERENCE,
                 "Grouping \"%s\" references itself through a uses statement.", grp->name);
         return LY_EVALID;
     }
@@ -3436,7 +3433,7 @@
     if (grp->actions) {
         actions = parent ? lysc_node_actions_p(parent) : &ctx->cur_mod->compiled->rpcs;
         if (!actions) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "Invalid child %s \"%s\" of uses parent %s \"%s\" node.",
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid child %s \"%s\" of uses parent %s \"%s\" node.",
                     grp->actions[0].name, lys_nodetype2str(grp->actions[0].nodetype), parent->name,
                     lys_nodetype2str(parent->nodetype));
             ret = LY_EVALID;
@@ -3458,7 +3455,7 @@
     if (grp->notifs) {
         notifs = parent ? lysc_node_notifs_p(parent) : &ctx->cur_mod->compiled->notifs;
         if (!notifs) {
-            LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE, "Invalid child %s \"%s\" of uses parent %s \"%s\" node.",
+            LOGVAL(ctx->ctx, LYVE_REFERENCE, "Invalid child %s \"%s\" of uses parent %s \"%s\" node.",
                     grp->notifs[0].name, lys_nodetype2str(grp->notifs[0].nodetype), parent->name,
                     lys_nodetype2str(parent->nodetype));
             ret = LY_EVALID;
@@ -3478,7 +3475,7 @@
 
     /* check that all augments were applied */
     for (i = 0; i < ctx->uses_augs.count; ++i) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+        LOGVAL(ctx->ctx, LYVE_REFERENCE,
                 "Augment target node \"%s\" in grouping \"%s\" was not found.",
                 ((struct lysc_augment *)ctx->uses_augs.objs[i])->nodeid->expr, grp->name);
         ret = LY_ENOTFOUND;
@@ -3487,7 +3484,7 @@
 
     /* check that all refines were applied */
     for (i = 0; i < ctx->uses_rfns.count; ++i) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
+        LOGVAL(ctx->ctx, LYVE_REFERENCE,
                 "Refine(s) target node \"%s\" in grouping \"%s\" was not found.",
                 ((struct lysc_refine *)ctx->uses_rfns.objs[i])->nodeid->expr, grp->name);
         ret = LY_ENOTFOUND;
@@ -3652,7 +3649,7 @@
     }
 
     if (parent && (parent->flags & LYS_CONFIG_R) && (node->flags & LYS_CONFIG_W)) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_SEMANTICS,
+        LOGVAL(ctx->ctx, LYVE_SEMANTICS,
                 "Configuration node cannot be child of any state data node.");
         return LY_EVALID;
     }
@@ -3802,7 +3799,7 @@
 cleanup:
     ctx->options = prev_opts;
     if (ret && dev_pnode) {
-        LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_OTHER, "Compilation of a deviated and/or refined node failed.");
+        LOGVAL(ctx->ctx, LYVE_OTHER, "Compilation of a deviated and/or refined node failed.");
     }
     lysp_dev_node_free(ctx->ctx, dev_pnode);
     lysc_update_path(ctx, NULL, NULL);
diff --git a/src/schema_compile_node.h b/src/schema_compile_node.h
index 6e1fc09..38ad6ab 100644
--- a/src/schema_compile_node.h
+++ b/src/schema_compile_node.h
@@ -54,12 +54,11 @@
  * @brief Checks pattern syntax.
  *
  * @param[in] ctx Context.
- * @param[in] log_path Path for logging errors.
  * @param[in] pattern Pattern to check.
  * @param[in,out] pcre2_code Compiled PCRE2 pattern. If NULL, the compiled information used to validate pattern are freed.
  * @return LY_ERR value - LY_SUCCESS, LY_EMEM, LY_EVALID.
  */
-LY_ERR lys_compile_type_pattern_check(struct ly_ctx *ctx, const char *log_path, const char *pattern, pcre2_code **code);
+LY_ERR lys_compile_type_pattern_check(struct ly_ctx *ctx, const char *pattern, pcre2_code **code);
 
 /**
  * @brief Compile information about the leaf/leaf-list's type.
diff --git a/src/schema_features.c b/src/schema_features.c
index 15ffed9..bbcfa6f 100644
--- a/src/schema_features.c
+++ b/src/schema_features.c
@@ -299,8 +299,7 @@
             uint64_t spaces;
             for (spaces = 0; c[i + op_len + spaces] && isspace(c[i + op_len + spaces]); spaces++) {}
             if (c[i + op_len + spaces] == '\0') {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_SYNTAX_YANG,
-                        "Invalid value \"%s\" of if-feature - unexpected end of expression.", qname->str);
+                LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - unexpected end of expression.", qname->str);
                 return LY_EVALID;
             } else if (!isspace(c[i + op_len])) {
                 /* feature name starting with the not/and/or */
@@ -316,7 +315,7 @@
                 }
             } else { /* and, or */
                 if (f_exp != f_size) {
-                    LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_SYNTAX_YANG,
+                    LOGVAL(ctx, LYVE_SYNTAX_YANG,
                             "Invalid value \"%s\" of if-feature - missing feature/expression before \"%.*s\" operation.",
                             qname->str, op_len, &c[i]);
                     return LY_EVALID;
@@ -343,14 +342,12 @@
     }
     if (j) {
         /* not matching count of ( and ) */
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_SYNTAX_YANG,
-                "Invalid value \"%s\" of if-feature - non-matching opening and closing parentheses.", qname->str);
+        LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - non-matching opening and closing parentheses.", qname->str);
         return LY_EVALID;
     }
     if (f_exp != f_size) {
         /* features do not match the needed arguments for the logical operations */
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_SYNTAX_YANG,
-                "Invalid value \"%s\" of if-feature - number of features in expression does not match "
+        LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - number of features in expression does not match "
                 "the required number of operands for the operations.", qname->str);
         return LY_EVALID;
     }
@@ -358,8 +355,7 @@
     if (checkversion || (expr_size > 1)) {
         /* check that we have 1.1 module */
         if (qname->mod->version != LYS_VERSION_1_1) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_SYNTAX_YANG,
-                    "Invalid value \"%s\" of if-feature - YANG 1.1 expression in YANG 1.0 module.", qname->str);
+            LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - YANG 1.1 expression in YANG 1.0 module.", qname->str);
             return LY_EVALID;
         }
     }
@@ -427,7 +423,7 @@
             /* now get the link to the feature definition */
             f = lysp_feature_find(qname->mod, &c[i], j - i, 1);
             if (!f) {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_SYNTAX_YANG,
+                LOGVAL(ctx, LYVE_SYNTAX_YANG,
                         "Invalid value \"%s\" of if-feature - unable to find feature \"%.*s\".", qname->str, j - i, &c[i]);
                 rc = LY_EVALID;
                 goto error;
@@ -444,8 +440,7 @@
 
     if (++expr_size || ++f_size) {
         /* not all expected operators and operands found */
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_SYNTAX_YANG,
-                "Invalid value \"%s\" of if-feature - processing error.", qname->str);
+        LOGVAL(ctx, LYVE_SYNTAX_YANG, "Invalid value \"%s\" of if-feature - processing error.", qname->str);
         rc = LY_EINT;
     } else {
         rc = LY_SUCCESS;
@@ -636,8 +631,7 @@
 
     for (u = 0; u < LY_ARRAY_COUNT(depfeatures); ++u) {
         if (feature == depfeatures[u]) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Feature \"%s\" is indirectly referenced from itself.",
-                    feature->name);
+            LOGVAL(ctx, LYVE_REFERENCE, "Feature \"%s\" is indirectly referenced from itself.", feature->name);
             ret = LY_EVALID;
             goto cleanup;
         }
@@ -649,8 +643,7 @@
         drv = recursion.objs[v];
         for (u = 0; u < LY_ARRAY_COUNT(drv->depfeatures); ++u) {
             if (feature == drv->depfeatures[u]) {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Feature \"%s\" is indirectly referenced from itself.",
-                        feature->name);
+                LOGVAL(ctx, LYVE_REFERENCE, "Feature \"%s\" is indirectly referenced from itself.", feature->name);
                 ret = LY_EVALID;
                 goto cleanup;
             }
@@ -686,8 +679,7 @@
             LY_ARRAY_FOR(f->iffeatures_c[u].features, v) {
                 /* check for circular dependency - direct reference first,... */
                 if (f == f->iffeatures_c[u].features[v]) {
-                    LOGVAL(pmod->mod->ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Feature \"%s\" is referenced from itself.",
-                            f->name);
+                    LOGVAL(pmod->mod->ctx, LYVE_REFERENCE, "Feature \"%s\" is referenced from itself.", f->name);
                     return LY_EVALID;
                 }
                 /* ... and indirect circular reference */
diff --git a/src/tree_data.c b/src/tree_data.c
index e466505..ba12500 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -56,7 +56,7 @@
 LY_ERR
 lyd_value_store(const struct ly_ctx *ctx, struct lyd_value *val, const struct lysc_type *type, const char *value,
         size_t value_len, ly_bool *dynamic, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints,
-        const struct lysc_node *ctx_node, ly_bool *incomplete, enum LY_VLOG_ELEM log_elem_type, const void *log_elem)
+        const struct lysc_node *ctx_node, ly_bool *incomplete)
 {
     LY_ERR ret;
     struct ly_err_item *err = NULL;
@@ -73,10 +73,10 @@
         }
     } else if (ret) {
         if (err) {
-            LOGVAL(ctx, log_elem_type, log_elem, err->vecode, err->msg);
+            LOGVAL(ctx, err->vecode, err->msg);
             ly_err_free(err);
         } else {
-            LOGVAL(ctx, log_elem_type, log_elem, LYVE_OTHER, "Storing value \"%.*s\" failed.", (int)value_len, value);
+            LOGVAL(ctx, LYVE_OTHER, "Storing value \"%.*s\" failed.", (int)value_len, value);
         }
         return ret;
     }
@@ -89,7 +89,7 @@
 
 LY_ERR
 lyd_value_validate_incomplete(const struct ly_ctx *ctx, const struct lysc_type *type, struct lyd_value *val,
-        const struct lyd_node *ctx_node, const struct lyd_node *tree, enum LY_VLOG_ELEM log_elem_type, const void *log_elem)
+        const struct lyd_node *ctx_node, const struct lyd_node *tree)
 {
     LY_ERR ret;
     struct ly_err_item *err = NULL;
@@ -99,10 +99,10 @@
     ret = type->plugin->validate(ctx, type, ctx_node, tree, val, &err);
     if (ret) {
         if (err) {
-            LOGVAL(ctx, log_elem_type, log_elem, err->vecode, err->msg);
+            LOGVAL(ctx, err->vecode, err->msg);
             ly_err_free(err);
         } else {
-            LOGVAL(ctx, log_elem_type, log_elem, LYVE_OTHER, "Resolving value \"%s\" failed.", val->canonical);
+            LOGVAL(ctx, LYVE_OTHER, "Resolving value \"%s\" failed.", val->canonical);
         }
         return ret;
     }
@@ -136,7 +136,9 @@
     } else if (rc && err) {
         if (ctx) {
             /* log only in case the ctx was provided as input parameter */
-            LOGVAL(ctx, LY_VLOG_STR, err->path, err->vecode, err->msg);
+            LOG_LOCSET(ctx, NULL, NULL, err->path, NULL);
+            LOGVAL(ctx, err->vecode, err->msg);
+            LOG_LOCBACK(ctx, 0, 0, 1, 0);
         }
         ly_err_free(err);
     }
@@ -179,7 +181,9 @@
     if (rc) {
         if (err) {
             if (ctx) {
-                LOGVAL(ctx, LY_VLOG_LYD, node, err->vecode, err->msg);
+                LOG_LOCSET(ctx, NULL, (const struct lyd_node *)node, NULL, NULL);
+                LOGVAL(ctx, err->vecode, err->msg);
+                LOG_LOCBACK(ctx, 0, 1, 0, 0);
             }
             ly_err_free(err);
         }
@@ -215,8 +219,9 @@
     type = ((struct lysc_node_leaf *)node->schema)->type;
 
     /* store the value */
-    ret = lyd_value_store(ctx, &val, type, value, value_len, NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, node->schema,
-            NULL, LY_VLOG_LYSC, node->schema);
+    LOG_LOCSET(ctx, node->schema, (const struct lyd_node *)node, NULL, NULL);
+    ret = lyd_value_store(ctx, &val, type, value, value_len, NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, node->schema, NULL);
+    LOG_LOCBACK(ctx, 1, 1, 0, 0);
     LY_CHECK_RET(ret);
 
     /* compare values */
@@ -533,8 +538,10 @@
     term->prev = (struct lyd_node *)term;
     term->flags = LYD_NEW;
 
+    LOG_LOCSET(schema->module->ctx, schema, NULL, NULL, NULL);
     ret = lyd_value_store(schema->module->ctx, &term->value, ((struct lysc_node_leaf *)term->schema)->type, value,
-            value_len, dynamic, format, prefix_data, hints, schema, incomplete, LY_VLOG_LYSC, schema);
+            value_len, dynamic, format, prefix_data, hints, schema, incomplete);
+    LOG_LOCBACK(schema->module->ctx, 1, 0, 0, 0);
     LY_CHECK_ERR_RET(ret, free(term), ret);
     lyd_hash((struct lyd_node *)term);
 
@@ -610,6 +617,8 @@
     /* create list */
     LY_CHECK_GOTO(ret = lyd_create_inner(schema, &list), cleanup);
 
+    LOG_LOCSET(schema->module->ctx, NULL, list, NULL, NULL);
+
     /* create and insert all the keys */
     LY_ARRAY_FOR(predicates, u) {
         LY_CHECK_GOTO(ret = lyd_create_term2(predicates[u].key, &predicates[u].value, &key), cleanup);
@@ -624,6 +633,7 @@
     list = NULL;
 
 cleanup:
+    LOG_LOCBACK(schema->module->ctx, 0, 1, 0, 0);
     lyd_free_tree(list);
     return ret;
 }
@@ -637,6 +647,8 @@
     enum ly_path_pred_type pred_type = 0;
     struct ly_path_predicate *predicates = NULL;
 
+    LOG_LOCSET(schema->module->ctx, schema, NULL, NULL, NULL);
+
     /* parse keys */
     LY_CHECK_GOTO(ret = ly_path_parse_predicate(schema->module->ctx, NULL, keys, keys_len, LY_PATH_PREFIX_OPTIONAL,
             LY_PATH_PRED_KEYS, &expr), cleanup);
@@ -649,6 +661,7 @@
     LY_CHECK_GOTO(ret = lyd_create_list(schema, predicates, node), cleanup);
 
 cleanup:
+    LOG_LOCBACK(schema->module->ctx, 1, 0, 0, 0);
     lyxp_expr_free(schema->module->ctx, expr);
     ly_path_predicates_free(schema->module->ctx, pred_type, predicates);
     return ret;
@@ -1150,8 +1163,10 @@
     type = ((struct lysc_node_leaf *)term->schema)->type;
 
     /* parse the new value */
+    LOG_LOCSET(LYD_CTX(term), term->schema, term, NULL, NULL);
     ret = lyd_value_store(LYD_CTX(term), &val, type, val_str, strlen(val_str), NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA,
-            term->schema, NULL, LY_VLOG_LYD, term);
+            term->schema, NULL);
+    LOG_LOCBACK(LYD_CTX(term), term->schema ? 1 : 0, 1, 0, 0);
     LY_CHECK_GOTO(ret, cleanup);
 
     /* compare original and new value */
@@ -1291,8 +1306,10 @@
     schema = p[LY_ARRAY_COUNT(p) - 1].node;
     if ((schema->nodetype == LYS_LIST) && (p[LY_ARRAY_COUNT(p) - 1].pred_type == LY_PATH_PREDTYPE_NONE) &&
             !(options & LYD_NEW_PATH_OPAQ)) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
-                lys_nodetype2str(schema->nodetype), schema->name);
+        LOG_LOCSET(ctx, schema, NULL, NULL, NULL);
+        LOGVAL(ctx, LYVE_XPATH, "Predicate missing for %s \"%s\" in path \"%s\".",
+                lys_nodetype2str(schema->nodetype), schema->name, path);
+        LOG_LOCBACK(ctx, 1, 0, 0, 0);
         ret = LY_EINVAL;
         goto cleanup;
     } else if ((schema->nodetype == LYS_LEAFLIST) && (p[LY_ARRAY_COUNT(p) - 1].pred_type == LY_PATH_PREDTYPE_NONE)) {
@@ -1311,7 +1328,7 @@
             LY_ARRAY_NEW_GOTO(ctx, p[LY_ARRAY_COUNT(p) - 1].predicates, pred, ret, cleanup);
 
             ret = lyd_value_store(ctx, &pred->value, ((struct lysc_node_leaflist *)schema)->type, value, strlen(value),
-                    NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, schema, NULL, LY_VLOG_LYSC, schema);
+                    NULL, LY_PREF_JSON, NULL, LYD_HINT_DATA, schema, NULL);
             LY_CHECK_GOTO(ret, cleanup);
             ++((struct lysc_type *)pred->value.realtype)->refcount;
         } /* else we have opaq flag and the value is not valid, leavne no predicate and then create an opaque node */
@@ -1323,7 +1340,9 @@
         if (ret == LY_SUCCESS) {
             /* the node exists, are we supposed to update it or is it just a default? */
             if (!(options & LYD_NEW_PATH_UPDATE) && !(node->flags & LYD_DEFAULT)) {
-                LOGERR(ctx, LY_EEXIST, "Path \"%s\" already exists", path);
+                LOG_LOCSET(ctx, NULL, node, NULL, NULL);
+                LOGVAL(ctx, LYVE_REFERENCE, "Path \"%s\" already exists", path);
+                LOG_LOCBACK(ctx, 0, 1, 0, 0);
                 ret = LY_EEXIST;
                 goto cleanup;
             }
@@ -2234,13 +2253,15 @@
         size_t name_len, const char *value, size_t value_len, ly_bool *dynamic, LY_PREFIX_FORMAT format,
         void *prefix_data, uint32_t hints, ly_bool clear_dflt, ly_bool *incomplete)
 {
-    LY_ERR rc;
+    LY_ERR ret = LY_SUCCESS;
     struct lysc_ext_instance *ant = NULL;
     struct lyd_meta *mt, *last;
     LY_ARRAY_COUNT_TYPE u;
 
     assert((parent || meta) && mod);
 
+    LOG_LOCSET(mod->ctx, parent ? parent->schema : NULL, parent, NULL, NULL);
+
     LY_ARRAY_FOR(mod->compiled->exts, u) {
         if ((mod->compiled->exts[u].def->plugin == lyext_plugins_internal[LYEXT_PLUGIN_INTERNAL_ANNOTATION].plugin) &&
                 !ly_strncmp(mod->compiled->exts[u].argument, name, name_len)) {
@@ -2251,20 +2272,21 @@
     }
     if (!ant) {
         /* attribute is not defined as a metadata annotation (RFC 7952) */
-        LOGERR(mod->ctx, LY_EINVAL, "Annotation definition for attribute \"%s:%.*s\" not found.",
+        LOGVAL(mod->ctx, LYVE_REFERENCE, "Annotation definition for attribute \"%s:%.*s\" not found.",
                 mod->name, name_len, name);
-        return LY_EINVAL;
+        ret = LY_EINVAL;
+        goto cleanup;
     }
 
     mt = calloc(1, sizeof *mt);
-    LY_CHECK_ERR_RET(!mt, LOGMEM(mod->ctx), LY_EMEM);
+    LY_CHECK_ERR_GOTO(!mt, LOGMEM(mod->ctx); ret = LY_EMEM, cleanup);
     mt->parent = parent;
     mt->annotation = ant;
-    rc = lyd_value_store(mod->ctx, &mt->value, ((struct lyext_metadata *)ant->data)->type, value, value_len, dynamic,
-            format, prefix_data, hints, parent ? parent->schema : NULL, incomplete, LY_VLOG_NONE, NULL);
-    LY_CHECK_ERR_RET(rc, free(mt), rc);
-    rc = lydict_insert(mod->ctx, name, name_len, &mt->name);
-    LY_CHECK_ERR_RET(rc, free(mt), rc);
+    ret = lyd_value_store(mod->ctx, &mt->value, ((struct lyext_metadata *)ant->data)->type, value, value_len, dynamic,
+            format, prefix_data, hints, parent ? parent->schema : NULL, incomplete);
+    LY_CHECK_ERR_GOTO(ret, free(mt), cleanup);
+    ret = lydict_insert(mod->ctx, name, name_len, &mt->name);
+    LY_CHECK_ERR_GOTO(ret, free(mt), cleanup);
 
     /* insert as the last attribute */
     if (parent) {
@@ -2277,7 +2299,10 @@
     if (meta) {
         *meta = mt;
     }
-    return LY_SUCCESS;
+
+cleanup:
+    LOG_LOCBACK(mod->ctx, (parent && parent->schema) ? 1 : 0, parent ? 1 : 0, 0, 0);
+    return ret;
 }
 
 void
diff --git a/src/tree_data_helpers.c b/src/tree_data_helpers.c
index 188744b..78f53af 100644
--- a/src/tree_data_helpers.c
+++ b/src/tree_data_helpers.c
@@ -239,7 +239,7 @@
     key = lyd_child(node);
     while ((skey = lys_getnext(skey, node->schema, NULL, 0)) && (skey->flags & LYS_KEY)) {
         if (!key || (key->schema != skey)) {
-            LOGVAL(LYD_CTX(node), LY_VLOG_LYD, node, LY_VCODE_NOKEY, skey->name);
+            LOGVAL(LYD_CTX(node), LY_VCODE_NOKEY, skey->name);
             return LY_EVALID;
         }
 
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index 5427621..ce690bb 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -316,14 +316,12 @@
  * @param[in] hints [Value hints](@ref lydvalhints) from the parser.
  * @param[in] ctx_node Context schema node.
  * @param[out] incomplete Optional, set if the value also needs to be resolved.
- * @param[in] log_elem_type Elem type for logging.
- * @param[in] log_elem Elem for logging.
  * @return LY_SUCCESS on success,
  * @return LY_ERR value on error.
  */
 LY_ERR lyd_value_store(const struct ly_ctx *ctx, struct lyd_value *val, const struct lysc_type *type, const char *value,
         size_t value_len, ly_bool *dynamic, LY_PREFIX_FORMAT format, void *prefix_data, uint32_t hints,
-        const struct lysc_node *ctx_node, ly_bool *incomplete, enum LY_VLOG_ELEM log_elem_type, const void *log_elem);
+        const struct lysc_node *ctx_node, ly_bool *incomplete);
 
 /**
  * @brief Validate previously incompletely stored value.
@@ -333,13 +331,11 @@
  * @param[in,out] val Stored value to resolve.
  * @param[in] ctx_node Context node for the resolution.
  * @param[in] tree Data tree for the resolution.
- * @param[in] log_elem_type Elem type for logging.
- * @param[in] log_elem Elem for logging.
  * @return LY_SUCCESS on success,
  * @return LY_ERR value on error.
  */
 LY_ERR lyd_value_validate_incomplete(const struct ly_ctx *ctx, const struct lysc_type *type, struct lyd_value *val,
-        const struct lyd_node *ctx_node, const struct lyd_node *tree, enum LY_VLOG_ELEM log_elem_type, const void *log_elem);
+        const struct lyd_node *ctx_node, const struct lyd_node *tree);
 
 /* generic function lys_value_validate */
 LY_ERR _lys_value_validate(const struct ly_ctx *ctx, const struct lysc_node *node, const char *value, size_t value_len,
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 61cbd1f..71d8101 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -94,11 +94,7 @@
 
 error:
     if (stmt) {
-        if (ctx) {
-            LOGVAL_PARSER(ctx, LY_VCODE_INVAL, date_len, date, stmt);
-        } else {
-            LOGVAL(NULL, LY_VLOG_NONE, NULL, LY_VCODE_INVAL, date_len, date, stmt);
-        }
+        LOGVAL_PARSER(ctx, LY_VCODE_INVAL, date_len, date, stmt);
     }
     return LY_EINVAL;
 }
@@ -670,13 +666,13 @@
 
         /* check that the submodule belongs-to our module */
         if (strcmp(info->submoduleof, submod->mod->name)) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Included \"%s\" submodule from \"%s\" belongs-to a different module \"%s\".",
+            LOGVAL(ctx, LYVE_REFERENCE, "Included \"%s\" submodule from \"%s\" belongs-to a different module \"%s\".",
                     submod->name, info->submoduleof, submod->mod->name);
             return LY_EVALID;
         }
         /* check circular dependency */
         if (submod->parsing) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "A circular dependency (include) for module \"%s\".", submod->name);
+            LOGVAL(ctx, LYVE_REFERENCE, "A circular dependency (include) for module \"%s\".", submod->name);
             return LY_EVALID;
         }
     }
@@ -806,8 +802,7 @@
     if (implement) {
         m = ly_ctx_get_module_implemented(ctx, name);
         if (m && (!*mod || (*mod && (m != *mod)))) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE,
-                    "Module \"%s\" is already present in other implemented revision.", name);
+            LOGVAL(ctx, LYVE_REFERENCE, "Module \"%s\" is already present in other implemented revision.", name);
             *mod = NULL;
             return LY_EDENIED;
         }
@@ -860,14 +855,13 @@
         }
 
         if (!*mod) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "%s \"%s\" module failed.",
-                    implement ? "Loading" : "Importing", name);
+            LOGVAL(ctx, LYVE_REFERENCE, "%s \"%s\" module failed.", implement ? "Loading" : "Importing", name);
             return LY_EVALID;
         }
     } else {
         /* we have module from the current context, circular check */
         if ((*mod)->parsed->parsing) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "A circular dependency (import) for module \"%s\".", name);
+            LOGVAL(ctx, LYVE_REFERENCE, "A circular dependency (import) for module \"%s\".", name);
             *mod = NULL;
             return LY_EVALID;
         }
@@ -988,8 +982,7 @@
         inc->submodule = submod;
     }
     if (!inc->submodule) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_REFERENCE, "Including \"%s\" submodule into \"%s\" failed.",
-                inc->name, pctx->parsed_mod->mod->name);
+        LOGVAL(ctx, LYVE_REFERENCE, "Including \"%s\" submodule into \"%s\" failed.", inc->name, pctx->parsed_mod->mod->name);
         return LY_EVALID;
     }
 
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 0848a31..a8c8b05 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -114,16 +114,7 @@
 };
 
 #define PARSER_CTX(CTX) ((CTX)->parsed_mod->mod->ctx)
-
-#define LOGVAL_PARSER(CTX, ...) (CTX)->format == LYS_IN_YANG ? LOGVAL_YANG(CTX, __VA_ARGS__) : LOGVAL_YIN(CTX, __VA_ARGS__)
-
-#define LOGVAL_YANG(CTX, ...) LOGVAL(PARSER_CTX(CTX), ((struct lys_yang_parser_ctx *)CTX)->pos_type, \
-                                     ((struct lys_yang_parser_ctx *)CTX)->pos_type == LY_VLOG_LINE ? \
-                                        (void *)&((struct lys_yang_parser_ctx *)CTX)->in->line : \
-                                        (void *)((struct lys_yang_parser_ctx *)CTX)->path, __VA_ARGS__)
-
-#define LOGVAL_YIN(CTX, ...) LOGVAL(PARSER_CTX(CTX), LY_VLOG_LINE, \
-                                     &((struct lys_yin_parser_ctx *)CTX)->xmlctx->in->line, __VA_ARGS__)
+#define LOGVAL_PARSER(CTX, ...) LOGVAL((CTX) ? PARSER_CTX(CTX) : NULL, __VA_ARGS__)
 
 struct lys_parser_ctx {
     LYS_INFORMAT format;            /**< parser format */
@@ -142,11 +133,7 @@
     struct ly_set grps_nodes;       /**< set of grouping nodes */
     struct lysp_module *parsed_mod; /**< (sub)module being parsed */
     struct lys_glob_unres *unres;   /**< global unres structure */
-    enum LY_VLOG_ELEM pos_type;     /**< */
     struct ly_in *in;               /**< input handler for the parser */
-
-    const char *path;           /**< path */
-
     uint64_t indent;                /**< current position on the line for YANG indentation */
 };
 
diff --git a/src/validation.c b/src/validation.c
index 0bc5ac4..6299dee 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -167,7 +167,7 @@
     LY_ERR ret;
     uint32_t i;
     const struct lysc_when *disabled;
-    struct lyd_node *node;
+    struct lyd_node *node = NULL;
 
     if (!node_when->count) {
         return LY_SUCCESS;
@@ -177,6 +177,7 @@
     do {
         --i;
         node = node_when->dnodes[i];
+        LOG_LOCSET(LYD_CTX(node), node->schema, node, NULL, NULL);
 
         /* evaluate all when expressions that affect this node's existence */
         ret = lyd_validate_node_when(*tree, node, node->schema, &disabled);
@@ -188,13 +189,15 @@
                     lyd_del_move_root(tree, node, mod);
                     if (diff) {
                         /* add into diff */
-                        LY_CHECK_RET(lyd_val_diff_add(node, LYD_DIFF_OP_DELETE, diff));
+                        ret = lyd_val_diff_add(node, LYD_DIFF_OP_DELETE, diff);
+                        LY_CHECK_GOTO(ret, error);
                     }
                     lyd_free_tree(node);
                 } else {
                     /* invalid data */
-                    LOGVAL(LYD_CTX(node), LY_VLOG_LYD, node, LY_VCODE_NOWHEN, disabled->cond->expr);
-                    return LY_EVALID;
+                    LOGVAL(LYD_CTX(node), LY_VCODE_NOWHEN, disabled->cond->expr);
+                    ret = LY_EVALID;
+                    goto error;
                 }
             } else {
                 /* when true */
@@ -205,11 +208,17 @@
             ly_set_rm_index(node_when, i, NULL);
         } else if (ret != LY_EINCOMPLETE) {
             /* error */
-            return ret;
+            goto error;
         }
+
+        LOG_LOCBACK(LYD_CTX(node), 1, 1, 0, 0);
     } while (i);
 
     return LY_SUCCESS;
+
+error:
+    LOG_LOCBACK(LYD_CTX(node), 1, 1, 0, 0);
+    return ret;
 }
 
 LY_ERR
@@ -242,8 +251,9 @@
             struct lysc_type *type = ((struct lysc_node_leaf *)node->schema)->type;
 
             /* resolve the value of the node */
-            ret = lyd_value_validate_incomplete(LYD_CTX(node), type, &node->value, (struct lyd_node *)node, *tree,
-                    LY_VLOG_LYD, node);
+            LOG_LOCSET(LYD_CTX(node), node->schema, (struct lyd_node *)node, NULL, NULL);
+            ret = lyd_value_validate_incomplete(LYD_CTX(node), type, &node->value, (struct lyd_node *)node, *tree);
+            LOG_LOCBACK(LYD_CTX(node), node->schema ? 1 : 0, 1, 0, 0);
             LY_CHECK_RET(ret);
 
             /* remove this node from the set */
@@ -261,8 +271,7 @@
             struct lysc_type *type = ((struct lyext_metadata *)meta->annotation->data)->type;
 
             /* validate and store the value of the metadata */
-            ret = lyd_value_validate_incomplete(LYD_CTX(meta->parent), type, &meta->value, meta->parent, *tree,
-                    LY_VLOG_NONE, NULL);
+            ret = lyd_value_validate_incomplete(LYD_CTX(meta->parent), type, &meta->value, meta->parent, *tree);
             LY_CHECK_RET(ret);
 
             /* remove this attr from the set */
@@ -317,7 +326,7 @@
     }
 
     if (fail) {
-        LOGVAL(node->schema->module->ctx, LY_VLOG_LYD, node, LY_VCODE_DUP, node->schema->name);
+        LOGVAL(node->schema->module->ctx, LY_VCODE_DUP, node->schema->name);
         return LY_EVALID;
     }
     return LY_SUCCESS;
@@ -340,6 +349,8 @@
     struct lyd_node *match, *to_del;
     ly_bool found;
 
+    LOG_LOCSET(choic->module->ctx, (const struct lysc_node *)choic, NULL, NULL, NULL);
+
     LY_LIST_FOR((struct lysc_node *)choic->cases, scase) {
         found = 0;
         iter = NULL;
@@ -361,7 +372,8 @@
             /* there should not be 2 old cases */
             if (old_case) {
                 /* old data from 2 cases */
-                LOGVAL(choic->module->ctx, LY_VLOG_LYSC, choic, LY_VCODE_DUPCASE, old_case->name, scase->name);
+                LOGVAL(choic->module->ctx, LY_VCODE_DUPCASE, old_case->name, scase->name);
+                LOG_LOCBACK(choic->module->ctx, 1, 0, 0, 0);
                 return LY_EVALID;
             }
 
@@ -370,7 +382,8 @@
         } else if (found == 2) {
             if (new_case) {
                 /* new data from 2 cases */
-                LOGVAL(choic->module->ctx, LY_VLOG_LYSC, choic, LY_VCODE_DUPCASE, new_case->name, scase->name);
+                LOGVAL(choic->module->ctx, LY_VCODE_DUPCASE, new_case->name, scase->name);
+                LOG_LOCBACK(choic->module->ctx, 1, 0, 0, 0);
                 return LY_EVALID;
             }
 
@@ -379,6 +392,8 @@
         }
     }
 
+    LOG_LOCBACK(choic->module->ctx, 1, 0, 0, 0);
+
     if (old_case && new_case) {
         /* auto-delete old case */
         iter = NULL;
@@ -574,12 +589,17 @@
             continue;
         }
 
+        LOG_LOCSET(LYD_CTX(node), node->schema, node, NULL, NULL);
+
         if (node->flags & LYD_NEW) {
+            LY_ERR ret;
+
             /* remove old default(s) of the new node if it exists */
             lyd_validate_autodel_dup(first, node, mod, &next, diff);
 
             /* then check new node instance duplicities */
-            LY_CHECK_RET(lyd_validate_duplicates(*first, node));
+            ret = lyd_validate_duplicates(*first, node);
+            LY_CHECK_ERR_RET(ret, LOG_LOCBACK(LYD_CTX(node), node->schema ? 1 : 0, 1, 0, 0), ret);
 
             /* this node is valid */
             node->flags &= ~LYD_NEW;
@@ -589,6 +609,8 @@
             /* remove leftover default nodes from a no-longer existing case */
             lyd_validate_autodel_case_dflt(first, node, mod, &next, diff);
         }
+
+        LOG_LOCBACK(LYD_CTX(node), node->schema ? 1 : 0, 1, 0, 0);
     }
 
     return LY_SUCCESS;
@@ -688,7 +710,7 @@
 
     if (!disabled) {
         /* node instance not found */
-        LOGVAL(snode->module->ctx, LY_VLOG_LYSC, snode, LY_VCODE_NOMAND, snode->name);
+        LOGVAL(snode->module->ctx, LY_VCODE_NOMAND, snode->name);
         return LY_EVALID;
     }
 
@@ -712,6 +734,7 @@
     uint32_t count = 0;
     struct lyd_node *iter;
     const struct lysc_when *disabled;
+    ly_bool invalid_instance = 0;
 
     assert(min || max);
 
@@ -728,6 +751,8 @@
         }
         if (max && (count > max)) {
             /* not satisifed */
+            LOG_LOCSET(snode->module->ctx, NULL, iter, NULL, NULL);
+            invalid_instance = 1;
             break;
         }
     }
@@ -742,15 +767,19 @@
         }
 
         if (!disabled) {
-            LOGVAL(snode->module->ctx, LY_VLOG_LYSC, snode, LY_VCODE_NOMIN, snode->name);
-            return LY_EVALID;
+            LOGVAL(snode->module->ctx, LY_VCODE_NOMIN, snode->name);
+            goto failure;
         }
     } else if (max && (count > max)) {
-        LOGVAL(snode->module->ctx, LY_VLOG_LYSC, snode, LY_VCODE_NOMAX, snode->name);
-        return LY_EVALID;
+        LOGVAL(snode->module->ctx, LY_VCODE_NOMAX, snode->name);
+        goto failure;
     }
 
     return LY_SUCCESS;
+
+failure:
+    LOG_LOCBACK(snode->module->ctx, 0, invalid_instance, 0, 0);
+    return LY_EVALID;
 }
 
 /**
@@ -876,7 +905,9 @@
 
                 ptr += strlen(ptr);
             }
-            LOGVAL(ctx, LY_VLOG_LYD, second, LY_VCODE_NOUNIQ, uniq_str, path1, path2);
+            LOG_LOCSET(ctx, NULL, second, NULL, NULL);
+            LOGVAL(ctx, LY_VCODE_NOUNIQ, uniq_str, path1, path2);
+            LOG_LOCBACK(ctx, 0, 1, 0, 0);
 
             free(path1);
             free(path2);
@@ -1032,6 +1063,7 @@
 lyd_validate_siblings_schema_r(const struct lyd_node *first, const struct lyd_node *parent,
         const struct lysc_node *sparent, const struct lysc_module *mod, uint32_t val_opts, LYD_VALIDATE_OP op)
 {
+    LY_ERR ret = LY_SUCCESS;
     const struct lysc_node *snode = NULL;
     struct lysc_node_list *slist;
     struct lysc_node_leaflist *sllist;
@@ -1045,38 +1077,51 @@
             continue;
         }
 
+        LOG_LOCSET(mod ? mod->mod->ctx : sparent->module->ctx, snode, NULL, NULL, NULL);
+
         /* check min-elements and max-elements */
         if (snode->nodetype == LYS_LIST) {
             slist = (struct lysc_node_list *)snode;
             if (slist->min || slist->max) {
-                LY_CHECK_RET(lyd_validate_minmax(first, parent, snode, slist->min, slist->max));
+                ret = lyd_validate_minmax(first, parent, snode, slist->min, slist->max);
+                LY_CHECK_GOTO(ret, error);
             }
         } else if (snode->nodetype == LYS_LEAFLIST) {
             sllist = (struct lysc_node_leaflist *)snode;
             if (sllist->min || sllist->max) {
-                LY_CHECK_RET(lyd_validate_minmax(first, parent, snode, sllist->min, sllist->max));
+                ret = lyd_validate_minmax(first, parent, snode, sllist->min, sllist->max);
+                LY_CHECK_GOTO(ret, error);
             }
 
         } else if (snode->flags & LYS_MAND_TRUE) {
             /* check generic mandatory existence */
-            LY_CHECK_RET(lyd_validate_mandatory(first, parent, snode));
+            ret = lyd_validate_mandatory(first, parent, snode);
+            LY_CHECK_GOTO(ret, error);
         }
 
         /* check unique */
         if (snode->nodetype == LYS_LIST) {
             slist = (struct lysc_node_list *)snode;
             if (slist->uniques) {
-                LY_CHECK_RET(lyd_validate_unique(first, snode, (const struct lysc_node_leaf ***)slist->uniques));
+                ret = lyd_validate_unique(first, snode, (const struct lysc_node_leaf ***)slist->uniques);
+                LY_CHECK_GOTO(ret, error);
             }
         }
 
         if (snode->nodetype & (LYS_CHOICE | LYS_CASE)) {
             /* go recursively for schema-only nodes */
-            LY_CHECK_RET(lyd_validate_siblings_schema_r(first, parent, snode, mod, val_opts, op));
+            ret = lyd_validate_siblings_schema_r(first, parent, snode, mod, val_opts, op);
+            LY_CHECK_GOTO(ret, error);
         }
+
+        LOG_LOCBACK(mod ? mod->mod->ctx : sparent->module->ctx, 1, 0, 0, 0);
     }
 
     return LY_SUCCESS;
+
+error:
+    LOG_LOCBACK(mod ? mod->mod->ctx : sparent->module->ctx, 1, 0, 0, 0);
+    return ret;
 }
 
 /**
@@ -1172,7 +1217,7 @@
         /* check the result */
         lyxp_set_cast(&xp_set, LYXP_SET_BOOLEAN);
         if (!xp_set.val.bln) {
-            LOGVAL(LYD_CTX(node), LY_VLOG_LYD, node, LY_VCODE_NOMUST, musts[u].cond->expr);
+            LOGVAL(LYD_CTX(node), LY_VCODE_NOMUST, musts[u].cond->expr);
             return LY_EVALID;
         }
     }
@@ -1184,6 +1229,7 @@
 lyd_validate_final_r(struct lyd_node *first, const struct lyd_node *parent, const struct lysc_node *sparent,
         const struct lys_module *mod, uint32_t val_opts, LYD_VALIDATE_OP op)
 {
+    const char *innode = NULL;
     struct lyd_node *next = NULL, *node;
 
     /* validate all restrictions of nodes themselves */
@@ -1193,23 +1239,25 @@
             break;
         }
 
+        LOG_LOCSET(LYD_CTX(first), node->schema, node, NULL, NULL);
+
         /* opaque data */
         if (!node->schema) {
-            LOGVAL(LYD_CTX(node), LY_VLOG_LYD, node, LYVE_DATA, "Opaque node \"%s\" found.",
-                    ((struct lyd_node_opaq *)node)->name.name);
+            LOGVAL(LYD_CTX(node), LYVE_DATA, "Opaque node \"%s\" found.", ((struct lyd_node_opaq *)node)->name.name);
+            LOG_LOCBACK(LYD_CTX(first), 0, 1, 0, 0);
             return LY_EVALID;
         }
 
         /* no state/input/output data */
         if ((val_opts & LYD_VALIDATE_NO_STATE) && (node->schema->flags & LYS_CONFIG_R)) {
-            LOGVAL(LYD_CTX(node), LY_VLOG_LYD, node, LY_VCODE_INNODE, "state", node->schema->name);
-            return LY_EVALID;
+            innode = "state";
+            goto invalid_node;
         } else if ((op == LYD_VALIDATE_OP_RPC) && (node->schema->flags & LYS_CONFIG_R)) {
-            LOGVAL(LYD_CTX(node), LY_VLOG_LYD, node, LY_VCODE_INNODE, "output", node->schema->name);
-            return LY_EVALID;
+            innode = "output";
+            goto invalid_node;
         } else if ((op == LYD_VALIDATE_OP_REPLY) && (node->schema->flags & LYS_CONFIG_W)) {
-            LOGVAL(LYD_CTX(node), LY_VLOG_LYD, node, LY_VCODE_INNODE, "input", node->schema->name);
-            return LY_EVALID;
+            innode = "input";
+            goto invalid_node;
         }
 
         /* obsolete data */
@@ -1219,6 +1267,8 @@
         LY_CHECK_RET(lyd_validate_must(node, op));
 
         /* node value was checked by plugins */
+
+        LOG_LOCBACK(LYD_CTX(first), 1, 1, 0, 0);
     }
 
     /* validate schema-based restrictions */
@@ -1242,6 +1292,11 @@
     }
 
     return LY_SUCCESS;
+
+invalid_node:
+    LOGVAL(LYD_CTX(node), LY_VCODE_INNODE, innode, node->schema->name);
+    LOG_LOCBACK(LYD_CTX(first), 1, 1, 0, 0);
+    return LY_EVALID;
 }
 
 /**
@@ -1499,6 +1554,8 @@
         tree = tree_sibling;
     }
 
+    LOG_LOCSET(LYD_CTX(op_node), NULL, op_node, NULL, NULL);
+
     /* prevalidate whole operation subtree */
     LY_CHECK_GOTO(ret = lyd_validate_subtree(op_node, &type_check, &type_meta_check, &when_check,
             op == LYD_VALIDATE_OP_REPLY ? LYD_IMPLICIT_OUTPUT : 0, diff), cleanup);
@@ -1515,6 +1572,7 @@
     LY_CHECK_GOTO(ret = lyd_validate_final_r(lyd_child(op_node), op_node, op_node->schema, NULL, 0, op), cleanup);
 
 cleanup:
+    LOG_LOCBACK(LYD_CTX(op_node), 0, 1, 0, 0);
     /* restore operation tree */
     lyd_unlink_tree(op_subtree);
     if (op_parent) {
diff --git a/src/xml.c b/src/xml.c
index 6f87b81..d72d07f 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -32,7 +32,9 @@
 #include "tree_data.h"
 
 /* Move input p by s characters, if EOF log with lyxml_ctx c */
-#define move_input(c, s) ly_in_skip(c->in, s); LY_CHECK_ERR_RET(!c->in->current[0], LOGVAL(c->ctx, LY_VLOG_LINE, &c->in->line, LY_VCODE_EOF), LY_EVALID)
+#define move_input(c, s) \
+    ly_in_skip(c->in, s); \
+    LY_CHECK_ERR_RET(!c->in->current[0], LOGVAL(c->ctx, LY_VCODE_EOF), LY_EVALID)
 
 /* Ignore whitespaces in the input string p */
 #define ign_xmlws(c) while (is_xmlws(*(c)->in->current)) {ly_in_skip(c->in, 1);}
@@ -99,11 +101,10 @@
 
     /* check NameStartChar (minus colon) */
     LY_CHECK_ERR_RET(ly_getutf8(&in, &c, &parsed),
-            LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INCHAR, in[0]),
+            LOGVAL(xmlctx->ctx, LY_VCODE_INCHAR, in[0]),
             LY_EVALID);
     LY_CHECK_ERR_RET(!is_xmlqnamestartchar(c),
-            LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX,
-            "Identifier \"%s\" starts with an invalid character.", in - parsed),
+            LOGVAL(xmlctx->ctx, LYVE_SYNTAX, "Identifier \"%s\" starts with an invalid character.", in - parsed),
             LY_EVALID);
 
     /* check rest of the identifier */
@@ -112,7 +113,7 @@
         ly_in_skip(xmlctx->in, parsed);
 
         rc = ly_getutf8(&in, &c, &parsed);
-        LY_CHECK_ERR_RET(rc, LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INCHAR, in[0]), LY_EVALID);
+        LY_CHECK_ERR_RET(rc, LOGVAL(xmlctx->ctx, LY_VCODE_INCHAR, in[0]), LY_EVALID);
     } while (is_xmlqnamechar(c));
 
     *start = s;
@@ -232,12 +233,12 @@
         if (xmlctx->in->current[0] == '\0') {
             /* EOF */
             if (xmlctx->elements.count) {
-                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
+                LOGVAL(ctx, LY_VCODE_EOF);
                 return LY_EVALID;
             }
             return LY_SUCCESS;
         } else if (xmlctx->in->current[0] != '<') {
-            LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
+            LOGVAL(ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
                     xmlctx->in->current, "element tag start ('<')");
             return LY_EVALID;
         }
@@ -260,19 +261,18 @@
                 endtag_len = ly_strlen_const("]]>");
             } else if (!strncmp(xmlctx->in->current, "DOCTYPE", ly_strlen_const("DOCTYPE"))) {
                 /* Document type declaration - not supported */
-                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_NSUPP, "Document Type Declaration");
+                LOGVAL(ctx,  LY_VCODE_NSUPP, "Document Type Declaration");
                 return LY_EVALID;
             } else {
-                LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Unknown XML section \"%.20s\".",
-                        &xmlctx->in->current[-2]);
+                LOGVAL(ctx, LYVE_SYNTAX, "Unknown XML section \"%.20s\".", &xmlctx->in->current[-2]);
                 return LY_EVALID;
             }
             rc = ign_todelim(xmlctx->in->current, endtag, endtag_len, &parsed);
-            LY_CHECK_ERR_RET(rc, LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_NTERM, sectname), LY_EVALID);
+            LY_CHECK_ERR_RET(rc, LOGVAL(ctx, LY_VCODE_NTERM, sectname), LY_EVALID);
             ly_in_skip(xmlctx->in, parsed + endtag_len);
         } else if (xmlctx->in->current[0] == '?') {
             rc = ign_todelim(xmlctx->in->current, "?>", 2, &parsed);
-            LY_CHECK_ERR_RET(rc, LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_NTERM, "Declaration"), LY_EVALID);
+            LY_CHECK_ERR_RET(rc, LOGVAL(ctx, LY_VCODE_NTERM, "Declaration"), LY_EVALID);
             ly_in_skip(xmlctx->in, parsed + 2);
         } else {
             /* other non-WS character */
@@ -399,8 +399,8 @@
                     buf[len++] = '\"';
                     in += ly_strlen_const("&quot;");
                 } else {
-                    LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX,
-                            "Entity reference \"%.*s\" not supported, only predefined references allowed.", 10, &in[offset - 1]);
+                    LOGVAL(ctx, LYVE_SYNTAX, "Entity reference \"%.*s\" not supported, only predefined references allowed.",
+                            10, &in[offset - 1]);
                     goto error;
                 }
                 offset = 0;
@@ -424,19 +424,18 @@
                         n = (LY_BASE_HEX * n) + u;
                     }
                 } else {
-                    LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Invalid character reference \"%.*s\".", 12, p);
+                    LOGVAL(ctx, LYVE_SYNTAX, "Invalid character reference \"%.*s\".", 12, p);
                     goto error;
 
                 }
 
                 LY_CHECK_ERR_GOTO(in[offset] != ';',
-                        LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP,
+                        LOGVAL(ctx, LY_VCODE_INSTREXP,
                         LY_VCODE_INSTREXP_len(&in[offset]), &in[offset], ";"),
                         error);
                 ++offset;
                 LY_CHECK_ERR_GOTO(ly_pututf8(&buf[len], n, &u),
-                        LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX,
-                        "Invalid character reference \"%.*s\" (0x%08x).", 12, p, n),
+                        LOGVAL(ctx, LYVE_SYNTAX, "Invalid character reference \"%.*s\" (0x%08x).", 12, p, n),
                         error);
                 len += u;
                 in += offset;
@@ -474,7 +473,7 @@
     }
 
     /* EOF reached before endchar */
-    LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
+    LOGVAL(ctx, LY_VCODE_EOF);
 
 error:
     free(buf);
@@ -517,7 +516,7 @@
 
     /* match opening and closing element tags */
     if (!xmlctx->elements.count) {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
+        LOGVAL(xmlctx->ctx, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
                 name_len, name);
         return LY_EVALID;
     }
@@ -525,8 +524,7 @@
     e = (struct lyxml_elem *)xmlctx->elements.objs[xmlctx->elements.count - 1];
     if ((e->prefix_len != prefix_len) || (e->name_len != name_len) ||
             (prefix_len && strncmp(prefix, e->prefix, e->prefix_len)) || strncmp(name, e->name, e->name_len)) {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX,
-                "Opening (\"%.*s%s%.*s\") and closing (\"%.*s%s%.*s\") elements tag mismatch.",
+        LOGVAL(xmlctx->ctx, LYVE_SYNTAX, "Opening (\"%.*s%s%.*s\") and closing (\"%.*s%s%.*s\") elements tag mismatch.",
                 e->prefix_len, e->prefix ? e->prefix : "", e->prefix ? ":" : "", e->name_len, e->name,
                 prefix_len, prefix ? prefix : "", prefix ? ":" : "", name_len, name);
         return LY_EVALID;
@@ -548,7 +546,7 @@
 
     /* parse closing tag */
     if (xmlctx->in->current[0] != '>') {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
+        LOGVAL(xmlctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
                 xmlctx->in->current, "element tag termination ('>')");
         return LY_EVALID;
     }
@@ -653,10 +651,10 @@
 
     /* skip '=' */
     if (xmlctx->in->current[0] == '\0') {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
+        LOGVAL(xmlctx->ctx, LY_VCODE_EOF);
         return LY_EVALID;
     } else if (xmlctx->in->current[0] != '=') {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
+        LOGVAL(xmlctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
                 xmlctx->in->current, "'='");
         return LY_EVALID;
     }
@@ -667,10 +665,10 @@
 
     /* find quotes */
     if (xmlctx->in->current[0] == '\0') {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
+        LOGVAL(xmlctx->ctx, LY_VCODE_EOF);
         return LY_EVALID;
     } else if ((xmlctx->in->current[0] != '\'') && (xmlctx->in->current[0] != '\"')) {
-        LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
+        LOGVAL(xmlctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
                 xmlctx->in->current, "either single or double quotation mark");
         return LY_EVALID;
     }
@@ -714,10 +712,10 @@
     while ((xmlctx->in->current[0] != '>') && (xmlctx->in->current[0] != '/')) {
         in = xmlctx->in->current;
         if (in[0] == '\0') {
-            LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
+            LOGVAL(xmlctx->ctx, LY_VCODE_EOF);
             return LY_EVALID;
         } else if ((ly_getutf8(&in, &c, &parsed) || !is_xmlqnamestartchar(c))) {
-            LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(in - parsed), in - parsed,
+            LOGVAL(xmlctx->ctx, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(in - parsed), in - parsed,
                     "element tag end ('>' or '/>') or an attribute");
             return LY_EVALID;
         }
@@ -796,6 +794,8 @@
     xmlctx->ctx = ctx;
     xmlctx->in = in;
 
+    LOG_LOCINIT(ctx, NULL, NULL, NULL, in);
+
     /* parse next element, if any */
     LY_CHECK_GOTO(ret = lyxml_next_element(xmlctx, &xmlctx->prefix, &xmlctx->prefix_len, &xmlctx->name,
             &xmlctx->name_len, &closing), cleanup);
@@ -804,8 +804,7 @@
         /* update status */
         xmlctx->status = LYXML_END;
     } else if (closing) {
-        LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
-                xmlctx->name_len, xmlctx->name);
+        LOGVAL(ctx, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").", xmlctx->name_len, xmlctx->name);
         ret = LY_EVALID;
         goto cleanup;
     } else {
@@ -897,7 +896,7 @@
             /* no attributes but a closing tag */
             ly_in_skip(xmlctx->in, 1);
             if (!xmlctx->in->current[0]) {
-                LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
+                LOGVAL(xmlctx->ctx, LY_VCODE_EOF);
                 ret = LY_EVALID;
                 goto cleanup;
             }
@@ -1019,6 +1018,8 @@
         return;
     }
 
+    LOG_LOCBACK(xmlctx->ctx, 0, 0, 0, 1);
+
     if (((xmlctx->status == LYXML_ELEM_CONTENT) || (xmlctx->status == LYXML_ATTR_CONTENT)) && xmlctx->dynamic) {
         free((char *)xmlctx->value);
     }
diff --git a/src/xpath.c b/src/xpath.c
index fdba8cd..49d5aa8 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -1846,14 +1846,14 @@
 {
     if (exp->used == tok_idx) {
         if (ctx) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_EOF);
+            LOGVAL(ctx, LY_VCODE_XP_EOF);
         }
         return LY_EINCOMPLETE;
     }
 
     if (want_tok && (exp->tokens[tok_idx] != want_tok)) {
         if (ctx) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK2, lyxp_print_token(exp->tokens[tok_idx]),
+            LOGVAL(ctx, LY_VCODE_XP_INTOK2, lyxp_print_token(exp->tokens[tok_idx]),
                     &exp->expr[exp->tok_pos[tok_idx]], lyxp_print_token(want_tok));
         }
         return LY_ENOT;
@@ -1880,14 +1880,14 @@
 {
     if (exp->used == tok_idx) {
         if (ctx) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_EOF);
+            LOGVAL(ctx, LY_VCODE_XP_EOF);
         }
         return LY_EINCOMPLETE;
     }
 
     if ((exp->tokens[tok_idx] != want_tok1) && (exp->tokens[tok_idx] != want_tok2)) {
         if (ctx) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[tok_idx]),
+            LOGVAL(ctx, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[tok_idx]),
                     &exp->expr[exp->tok_pos[tok_idx]]);
         }
         return LY_ENOT;
@@ -1994,8 +1994,7 @@
             rc = lyxp_check_token(ctx, exp, *tok_idx, LYXP_TOKEN_NONE);
             LY_CHECK_RET(rc);
             if ((exp->tokens[*tok_idx] != LYXP_TOKEN_NAMETEST) && (exp->tokens[*tok_idx] != LYXP_TOKEN_NODETYPE)) {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK,
-                        lyxp_print_token(exp->tokens[*tok_idx]), &exp->expr[exp->tok_pos[*tok_idx]]);
+                LOGVAL(ctx, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]), &exp->expr[exp->tok_pos[*tok_idx]]);
                 return LY_EVALID;
             }
         /* fall through */
@@ -2025,8 +2024,7 @@
             }
             break;
         default:
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK,
-                    lyxp_print_token(exp->tokens[*tok_idx]), &exp->expr[exp->tok_pos[*tok_idx]]);
+            LOGVAL(ctx, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]), &exp->expr[exp->tok_pos[*tok_idx]]);
             return LY_EVALID;
         }
     } while (!exp_check_token2(NULL, exp, *tok_idx, LYXP_TOKEN_OPER_PATH, LYXP_TOKEN_OPER_RPATH));
@@ -2248,7 +2246,7 @@
         break;
     }
     if (min_arg_count == -1) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INFUNC, exp->tok_len[*tok_idx], &exp->expr[exp->tok_pos[*tok_idx]]);
+        LOGVAL(ctx, LY_VCODE_XP_INFUNC, exp->tok_len[*tok_idx], &exp->expr[exp->tok_pos[*tok_idx]]);
         return LY_EINVAL;
     }
     ++(*tok_idx);
@@ -2281,8 +2279,7 @@
     ++(*tok_idx);
 
     if ((arg_count < (uint32_t)min_arg_count) || (arg_count > max_arg_count)) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INARGCOUNT, arg_count, exp->tok_len[func_tok_idx],
-                &exp->expr[exp->tok_pos[func_tok_idx]]);
+        LOGVAL(ctx, LY_VCODE_XP_INARGCOUNT, arg_count, exp->tok_len[func_tok_idx], &exp->expr[exp->tok_pos[func_tok_idx]]);
         return LY_EVALID;
     }
 
@@ -2357,8 +2354,7 @@
         goto predicate;
         break;
     default:
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK,
-                lyxp_print_token(exp->tokens[*tok_idx]), &exp->expr[exp->tok_pos[*tok_idx]]);
+        LOGVAL(ctx, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]), &exp->expr[exp->tok_pos[*tok_idx]]);
         return LY_EVALID;
     }
 
@@ -2672,7 +2668,7 @@
     assert(expr_p);
 
     if (!expr_str[0]) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_EOF);
+        LOGVAL(ctx, LY_VCODE_XP_EOF);
         return LY_EVALID;
     }
 
@@ -2680,7 +2676,7 @@
         expr_len = strlen(expr_str);
     }
     if (expr_len > UINT16_MAX) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "XPath expression cannot be longer than %ud characters.", UINT16_MAX);
+        LOGVAL(ctx, LYVE_XPATH, "XPath expression cannot be longer than %ud characters.", UINT16_MAX);
         return LY_EVALID;
     }
 
@@ -2774,7 +2770,7 @@
             /* Literal with ' */
             for (tok_len = 1; (expr_str[parsed + tok_len] != '\0') && (expr_str[parsed + tok_len] != '\''); ++tok_len) {}
             LY_CHECK_ERR_GOTO(expr_str[parsed + tok_len] == '\0',
-                    LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_EOE, expr_str[parsed], &expr_str[parsed]); ret = LY_EVALID,
+                    LOGVAL(ctx, LY_VCODE_XP_EOE, expr_str[parsed], &expr_str[parsed]); ret = LY_EVALID,
                     error);
             ++tok_len;
             tok_type = LYXP_TOKEN_LITERAL;
@@ -2784,7 +2780,7 @@
             /* Literal with " */
             for (tok_len = 1; (expr_str[parsed + tok_len] != '\0') && (expr_str[parsed + tok_len] != '\"'); ++tok_len) {}
             LY_CHECK_ERR_GOTO(expr_str[parsed + tok_len] == '\0',
-                    LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_EOE, expr_str[parsed], &expr_str[parsed]); ret = LY_EVALID,
+                    LOGVAL(ctx, LY_VCODE_XP_EOE, expr_str[parsed], &expr_str[parsed]); ret = LY_EVALID,
                     error);
             ++tok_len;
             tok_type = LYXP_TOKEN_LITERAL;
@@ -2877,12 +2873,12 @@
                 tok_type = LYXP_TOKEN_OPER_MATH;
 
             } else if (prev_function_check) {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Invalid character 0x%x ('%c'), perhaps \"%.*s\" is supposed to be a function call.",
+                LOGVAL(ctx, LYVE_XPATH, "Invalid character 0x%x ('%c'), perhaps \"%.*s\" is supposed to be a function call.",
                         expr_str[parsed], expr_str[parsed], expr->tok_len[expr->used - 1], &expr->expr[expr->tok_pos[expr->used - 1]]);
                 ret = LY_EVALID;
                 goto error;
             } else {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INEXPR, parsed + 1, expr_str);
+                LOGVAL(ctx, LY_VCODE_XP_INEXPR, parsed + 1, expr_str);
                 ret = LY_EVALID;
                 goto error;
             }
@@ -2897,7 +2893,7 @@
             /* NameTest (NCName ':' '*' | QName) or NodeType/FunctionName */
             long int ncname_len = parse_ncname(&expr_str[parsed]);
             LY_CHECK_ERR_GOTO(ncname_len < 0,
-                    LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INEXPR, parsed - ncname_len + 1, expr_str); ret = LY_EVALID,
+                    LOGVAL(ctx, LY_VCODE_XP_INEXPR, parsed - ncname_len + 1, expr_str); ret = LY_EVALID,
                     error);
             tok_len = ncname_len;
 
@@ -2908,7 +2904,7 @@
                 } else {
                     ncname_len = parse_ncname(&expr_str[parsed + tok_len]);
                     LY_CHECK_ERR_GOTO(ncname_len < 0,
-                            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INEXPR, parsed - ncname_len + 1, expr_str); ret = LY_EVALID,
+                            LOGVAL(ctx, LY_VCODE_XP_INEXPR, parsed - ncname_len + 1, expr_str); ret = LY_EVALID,
                             error);
                     tok_len += ncname_len;
                 }
@@ -2939,7 +2935,7 @@
         /* fill repeat */
         LY_CHECK_ERR_GOTO(reparse_or_expr(ctx, expr, &tok_idx), ret = LY_EVALID, error);
         if (expr->used > tok_idx) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of an XPath expression.",
+            LOGVAL(ctx, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of an XPath expression.",
                     &expr->expr[expr->tok_pos[tok_idx]]);
             ret = LY_EVALID;
             goto error;
@@ -3408,8 +3404,7 @@
     }
 
     if (args[0]->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]),
-                "bit-is-set(node-set, string)");
+        LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "bit-is-set(node-set, string)");
         return LY_EVALID;
     }
     rc = lyxp_set_cast(args[1], LYXP_SET_STRING);
@@ -3630,7 +3625,7 @@
     }
 
     if (args[0]->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "count(node-set)");
+        LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "count(node-set)");
         return LY_EVALID;
     }
 
@@ -3652,7 +3647,7 @@
 xpath_current(struct lyxp_set **args, uint16_t arg_count, struct lyxp_set *set, uint32_t options)
 {
     if (arg_count || args) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGCOUNT, arg_count, "current()");
+        LOGVAL(set->ctx, LY_VCODE_XP_INARGCOUNT, arg_count, "current()");
         return LY_EVALID;
     }
 
@@ -3723,7 +3718,7 @@
     }
 
     if (args[0]->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "deref(node-set)");
+        LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "deref(node-set)");
         return LY_EVALID;
     }
 
@@ -3793,8 +3788,7 @@
     }
 
     if (args[0]->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]),
-                "derived-from(-or-self)(node-set, string)");
+        LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "derived-from(-or-self)(node-set, string)");
         return LY_EVALID;
     }
     rc = lyxp_set_cast(args[1], LYXP_SET_STRING);
@@ -3927,7 +3921,7 @@
     }
 
     if (args[0]->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "enum-value(node-set)");
+        LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "enum-value(node-set)");
         return LY_EVALID;
     }
 
@@ -4024,7 +4018,7 @@
     LY_CHECK_RET(rc);
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INCTX, print_set_type(set), "lang(string)");
+        LOGVAL(set->ctx, LY_VCODE_XP_INCTX, print_set_type(set), "lang(string)");
         return LY_EVALID;
     } else if (!set->used) {
         set_fill_boolean(set, 0);
@@ -4103,7 +4097,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INCTX, print_set_type(set), "last()");
+        LOGVAL(set->ctx, LY_VCODE_XP_INCTX, print_set_type(set), "last()");
         return LY_EVALID;
     } else if (!set->used) {
         set_fill_number(set, 0);
@@ -4139,7 +4133,7 @@
 
     if (arg_count) {
         if (args[0]->type != LYXP_SET_NODE_SET) {
-            LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]),
+            LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]),
                     "local-name(node-set?)");
             return LY_EVALID;
         } else if (!args[0]->used) {
@@ -4153,7 +4147,7 @@
         item = &args[0]->val.nodes[0];
     } else {
         if (set->type != LYXP_SET_NODE_SET) {
-            LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INCTX, print_set_type(set), "local-name(node-set?)");
+            LOGVAL(set->ctx, LY_VCODE_XP_INCTX, print_set_type(set), "local-name(node-set?)");
             return LY_EVALID;
         } else if (!set->used) {
             set_fill_string(set, "", 0);
@@ -4210,7 +4204,7 @@
 
     if (arg_count) {
         if (args[0]->type != LYXP_SET_NODE_SET) {
-            LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "name(node-set?)");
+            LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "name(node-set?)");
             return LY_EVALID;
         } else if (!args[0]->used) {
             set_fill_string(set, "", 0);
@@ -4223,7 +4217,7 @@
         item = &args[0]->val.nodes[0];
     } else {
         if (set->type != LYXP_SET_NODE_SET) {
-            LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INCTX, print_set_type(set), "name(node-set?)");
+            LOGVAL(set->ctx, LY_VCODE_XP_INCTX, print_set_type(set), "name(node-set?)");
             return LY_EVALID;
         } else if (!set->used) {
             set_fill_string(set, "", 0);
@@ -4292,7 +4286,7 @@
 
     if (arg_count) {
         if (args[0]->type != LYXP_SET_NODE_SET) {
-            LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]),
+            LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]),
                     "namespace-uri(node-set?)");
             return LY_EVALID;
         } else if (!args[0]->used) {
@@ -4306,7 +4300,7 @@
         item = &args[0]->val.nodes[0];
     } else {
         if (set->type != LYXP_SET_NODE_SET) {
-            LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INCTX, print_set_type(set), "namespace-uri(node-set?)");
+            LOGVAL(set->ctx, LY_VCODE_XP_INCTX, print_set_type(set), "namespace-uri(node-set?)");
             return LY_EVALID;
         } else if (!set->used) {
             set_fill_string(set, "", 0);
@@ -4538,7 +4532,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INCTX, print_set_type(set), "position()");
+        LOGVAL(set->ctx, LY_VCODE_XP_INCTX, print_set_type(set), "position()");
         return LY_EVALID;
     } else if (!set->used) {
         set_fill_number(set, 0);
@@ -4568,7 +4562,6 @@
 {
     struct lysc_pattern **patterns = NULL, **pattern;
     struct lysc_node_leaf *sleaf;
-    char *path;
     LY_ERR rc = LY_SUCCESS;
     struct ly_err_item *err;
 
@@ -4599,9 +4592,9 @@
 
     LY_ARRAY_NEW_RET(set->ctx, patterns, pattern, LY_EMEM);
     *pattern = malloc(sizeof **pattern);
-    path = lyd_path(set->cur_node, LYD_PATH_STD, NULL, 0);
-    rc = lys_compile_type_pattern_check(set->ctx, path, args[1]->val.str, &(*pattern)->code);
-    free(path);
+    LOG_LOCSET(set->ctx, NULL, set->cur_node, NULL, NULL);
+    rc = lys_compile_type_pattern_check(set->ctx, args[1]->val.str, &(*pattern)->code);
+    LOG_LOCBACK(set->ctx, 0, 1, 0, 0);
     if (rc != LY_SUCCESS) {
         LY_ARRAY_FREE(patterns);
         return rc;
@@ -5047,7 +5040,7 @@
     set_fill_number(set, 0);
 
     if (args[0]->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "sum(node-set)");
+        LOGVAL(set->ctx, LY_VCODE_XP_INARGTYPE, 1, print_set_type(args[0]), "sum(node-set)");
         return LY_EVALID;
     } else if (!args[0]->used) {
         return LY_SUCCESS;
@@ -5098,7 +5091,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INCTX, print_set_type(set), "text()");
+        LOGVAL(set->ctx, LY_VCODE_XP_INCTX, print_set_type(set), "text()");
         return LY_EVALID;
     }
 
@@ -5282,11 +5275,7 @@
 
         /* check for errors and non-implemented modules, as they are not valid */
         if (!mod || !mod->implemented) {
-            if (set->type == LYXP_SET_SCNODE_SET) {
-                LOGVAL(set->ctx, LY_VLOG_LYSC, set->cur_scnode, LY_VCODE_XP_INMOD, pref_len, *qname);
-            } else {
-                LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INMOD, pref_len, *qname);
-            }
+            LOGVAL(set->ctx, LY_VCODE_XP_INMOD, pref_len, *qname);
             return LY_EVALID;
         }
 
@@ -5486,7 +5475,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -5555,7 +5544,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         ret = LY_EVALID;
         goto cleanup;
     }
@@ -5642,7 +5631,7 @@
     }
 
     if (set->type != LYXP_SET_SCNODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYSC, set->cur_scnode, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -5739,7 +5728,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -5824,7 +5813,7 @@
     }
 
     if (set->type != LYXP_SET_SCNODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYSC, set->cur_scnode, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -5915,7 +5904,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -5970,7 +5959,7 @@
     LY_ERR rc;
 
     if ((set1->type != LYXP_SET_NODE_SET) || (set2->type != LYXP_SET_NODE_SET)) {
-        LOGVAL(set1->ctx, LY_VLOG_LYD, set1->cur_node, LY_VCODE_XP_INOP_2, "union", print_set_type(set1), print_set_type(set2));
+        LOGVAL(set1->ctx, LY_VCODE_XP_INOP_2, "union", print_set_type(set1), print_set_type(set2));
         return LY_EVALID;
     }
 
@@ -6021,7 +6010,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -6166,7 +6155,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -6226,7 +6215,7 @@
     }
 
     if (set->type != LYXP_SET_SCNODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYSC, set->cur_scnode, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -6313,7 +6302,7 @@
     }
 
     if (set->type != LYXP_SET_NODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -6390,7 +6379,7 @@
     }
 
     if (set->type != LYXP_SET_SCNODE_SET) {
-        LOGVAL(set->ctx, LY_VLOG_LYSC, set->cur_scnode, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
+        LOGVAL(set->ctx, LY_VCODE_XP_INOP_1, "path operator", print_set_type(set));
         return LY_EVALID;
     }
 
@@ -7564,7 +7553,7 @@
         }
 
         if (!xpath_func) {
-            LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INFUNC, exp->tok_len[*tok_idx], &exp->expr[exp->tok_pos[*tok_idx]]);
+            LOGVAL(set->ctx, LY_VCODE_XP_INFUNC, exp->tok_len[*tok_idx], &exp->expr[exp->tok_pos[*tok_idx]]);
             return LY_EVALID;
         }
     }
@@ -7648,7 +7637,6 @@
         lyxp_set_free(args[i]);
     }
     free(args);
-
     return rc;
 }
 
@@ -7671,13 +7659,13 @@
         errno = 0;
         num = strtold(&exp->expr[exp->tok_pos[*tok_idx]], &endptr);
         if (errno) {
-            LOGVAL(ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INTOK, "Unknown", &exp->expr[exp->tok_pos[*tok_idx]]);
-            LOGVAL(ctx, LY_VLOG_LYD, set->cur_node, LYVE_XPATH, "Failed to convert \"%.*s\" into a long double (%s).",
+            LOGVAL(ctx, LY_VCODE_XP_INTOK, "Unknown", &exp->expr[exp->tok_pos[*tok_idx]]);
+            LOGVAL(ctx, LYVE_XPATH, "Failed to convert \"%.*s\" into a long double (%s).",
                     exp->tok_len[*tok_idx], &exp->expr[exp->tok_pos[*tok_idx]], strerror(errno));
             return LY_EVALID;
         } else if (endptr - &exp->expr[exp->tok_pos[*tok_idx]] != exp->tok_len[*tok_idx]) {
-            LOGVAL(ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INTOK, "Unknown", &exp->expr[exp->tok_pos[*tok_idx]]);
-            LOGVAL(ctx, LY_VLOG_LYD, set->cur_node, LYVE_XPATH, "Failed to convert \"%.*s\" into a long double.",
+            LOGVAL(ctx, LY_VCODE_XP_INTOK, "Unknown", &exp->expr[exp->tok_pos[*tok_idx]]);
+            LOGVAL(ctx, LYVE_XPATH, "Failed to convert \"%.*s\" into a long double.",
                     exp->tok_len[*tok_idx], &exp->expr[exp->tok_pos[*tok_idx]]);
             return LY_EVALID;
         }
@@ -7793,8 +7781,7 @@
         goto predicate;
 
     default:
-        LOGVAL(set->ctx, LY_VLOG_LYD, set->cur_node, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]),
-                &exp->expr[exp->tok_pos[*tok_idx]]);
+        LOGVAL(set->ctx, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]), &exp->expr[exp->tok_pos[*tok_idx]]);
         return LY_EVALID;
     }
 
@@ -8502,12 +8489,15 @@
     set->format = format;
     set->prefix_data = prefix_data;
 
+    LOG_LOCSET(set->ctx, NULL, set->cur_node, NULL, NULL);
+
     /* evaluate */
     rc = eval_expr_select(exp, &tok_idx, 0, set, options);
     if (rc != LY_SUCCESS) {
         lyxp_set_free_content(set);
     }
 
+    LOG_LOCBACK(set->ctx, 0, 1, 0, 0);
     return rc;
 }
 
@@ -8743,6 +8733,7 @@
 lyxp_atomize(const struct lyxp_expr *exp, const struct lys_module *cur_mod, LY_PREFIX_FORMAT format, void *prefix_data,
         const struct lysc_node *ctx_scnode, struct lyxp_set *set, uint32_t options)
 {
+    LY_ERR ret;
     uint16_t tok_idx = 0;
 
     LY_CHECK_ARG_RET(NULL, exp, set, LY_EINVAL);
@@ -8767,8 +8758,13 @@
     set->format = format;
     set->prefix_data = prefix_data;
 
+    LOG_LOCSET(set->ctx, set->cur_scnode, NULL, NULL, NULL);
+
     /* evaluate */
-    return eval_expr_select(exp, &tok_idx, 0, set, options);
+    ret = eval_expr_select(exp, &tok_idx, 0, set, options);
+
+    LOG_LOCBACK(set->ctx, 1, 0, 0, 0);
+    return ret;
 }
 
 API const char *