blob: b161d5096dfc00534e4481bbff7ed94fbc4a7efb [file] [log] [blame]
Radek Krejci5fe60cc2015-09-01 17:14:39 +02001/**
Michal Vasko95ea9ff2021-11-09 12:29:14 +01002 * @file log.c
3 * @author Radek Krejci <rkrejci@cesnet.cz>
4 * @brief libnetconf2 - log functions
Radek Krejci5fe60cc2015-09-01 17:14:39 +02005 *
Michal Vasko95ea9ff2021-11-09 12:29:14 +01006 * @copyright
Michal Vasko05532772021-06-03 12:12:38 +02007 * Copyright (c) 2015 - 2021 CESNET, z.s.p.o.
Radek Krejci5fe60cc2015-09-01 17:14:39 +02008 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +01009 * This source code is licensed under BSD 3-Clause License (the "License").
10 * You may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
Michal Vaskoafd416b2016-02-25 14:51:46 +010012 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +010013 * https://opensource.org/licenses/BSD-3-Clause
Radek Krejci5fe60cc2015-09-01 17:14:39 +020014 */
15
16#include <stdarg.h>
Radek Krejci5fe60cc2015-09-01 17:14:39 +020017#include <stdio.h>
18
Michal Vaskoa601f5c2015-12-08 14:33:03 +010019#include <libyang/libyang.h>
20
Michal Vaskob078fee2016-09-29 11:30:31 +020021#ifdef NC_ENABLED_SSH
22 #include <libssh/libssh.h>
23#endif
24
Michal Vasko7a20d2e2021-05-19 16:40:23 +020025#include "compat.h"
Michal Vasko1a38c862016-01-15 15:50:07 +010026#include "libnetconf.h"
Michal Vaskob078fee2016-09-29 11:30:31 +020027#include "log.h"
Radek Krejci5fe60cc2015-09-01 17:14:39 +020028
29/**
30 * @brief libnetconf verbose level variable
31 */
Václav Kubernáta4474cf2022-01-17 12:37:22 +010032ATOMIC_T verbose_level = 0;
Radek Krejci5fe60cc2015-09-01 17:14:39 +020033
Michal Vasko05532772021-06-03 12:12:38 +020034void (*depr_print_clb)(NC_VERB_LEVEL level, const char *msg);
35void (*print_clb)(const struct nc_session *session, NC_VERB_LEVEL level, const char *msg);
Michal Vasko206d3b12015-12-04 11:08:42 +010036
Radek Krejci5fe60cc2015-09-01 17:14:39 +020037API void
38nc_verbosity(NC_VERB_LEVEL level)
39{
Václav Kubernáta4474cf2022-01-17 12:37:22 +010040 ATOMIC_STORE_RELAXED(verbose_level, level);
Michal Vasko77367452021-02-16 16:32:18 +010041 ly_log_level((LY_LOG_LEVEL)level);
Radek Krejci5fe60cc2015-09-01 17:14:39 +020042}
43
44struct {
45 NC_VERB_LEVEL level;
46 const char *label;
47} verb[] = {
bhartb186eba2018-11-12 15:35:09 -060048 {NC_VERB_ERROR, "[ERR]"},
49 {NC_VERB_WARNING, "[WRN]"},
50 {NC_VERB_VERBOSE, "[INF]"},
Michal Vasko2733aad2020-04-16 09:01:52 +020051 {NC_VERB_DEBUG, "[DBG]"},
52 {NC_VERB_DEBUG_LOWLVL, "[DBL]"}
Radek Krejci5fe60cc2015-09-01 17:14:39 +020053};
54
Michal Vaskob078fee2016-09-29 11:30:31 +020055#ifdef NC_ENABLED_SSH
56
57API void
58nc_libssh_thread_verbosity(int level)
59{
60 ssh_set_log_level(level);
61}
62
63#endif
64
Radek Krejci5fe60cc2015-09-01 17:14:39 +020065static void
Michal Vasko05532772021-06-03 12:12:38 +020066prv_vprintf(const struct nc_session *session, NC_VERB_LEVEL level, const char *format, va_list args)
Radek Krejci5fe60cc2015-09-01 17:14:39 +020067{
Michal Vaskofe5e8c92021-04-14 08:23:12 +020068#define PRV_MSG_INIT_SIZE 256
69 va_list args2;
70 char *prv_msg;
71 void *mem;
72 int req_len;
Radek Krejci5fe60cc2015-09-01 17:14:39 +020073
Michal Vaskofe5e8c92021-04-14 08:23:12 +020074 prv_msg = malloc(PRV_MSG_INIT_SIZE);
75 if (!prv_msg) {
76 return;
77 }
78
79 va_copy(args2, args);
80
81 req_len = vsnprintf(prv_msg, PRV_MSG_INIT_SIZE - 1, format, args);
82 if (req_len == -1) {
83 goto cleanup;
84 } else if (req_len >= PRV_MSG_INIT_SIZE - 1) {
85 /* the length is not enough */
86 ++req_len;
87 mem = realloc(prv_msg, req_len);
88 if (!mem) {
89 goto cleanup;
90 }
91 prv_msg = mem;
92
93 /* now print the full message */
94 req_len = vsnprintf(prv_msg, req_len, format, args2);
95 if (req_len == -1) {
96 goto cleanup;
97 }
98 }
Radek Krejci5fe60cc2015-09-01 17:14:39 +020099
Michal Vasko206d3b12015-12-04 11:08:42 +0100100 if (print_clb) {
Michal Vasko05532772021-06-03 12:12:38 +0200101 print_clb(session, level, prv_msg);
102 } else if (depr_print_clb) {
103 depr_print_clb(level, prv_msg);
104 } else if (session && session->id) {
105 fprintf(stderr, "Session %u %s: %s\n", session->id, verb[level].label, prv_msg);
Michal Vasko206d3b12015-12-04 11:08:42 +0100106 } else {
107 fprintf(stderr, "%s: %s\n", verb[level].label, prv_msg);
108 }
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200109
Michal Vaskofe5e8c92021-04-14 08:23:12 +0200110cleanup:
111 free(prv_msg);
112#undef PRV_MSG_INIT_SIZE
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200113}
114
115void
Michal Vasko05532772021-06-03 12:12:38 +0200116prv_printf(const struct nc_session *session, NC_VERB_LEVEL level, const char *format, ...)
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200117{
118 va_list ap;
119
120 va_start(ap, format);
Michal Vasko05532772021-06-03 12:12:38 +0200121 prv_vprintf(session, level, format, ap);
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200122 va_end(ap);
123}
124
Michal Vaskofea54dc2016-02-17 13:12:16 +0100125static void
126nc_ly_log_clb(LY_LOG_LEVEL lvl, const char *msg, const char *UNUSED(path))
127{
Michal Vasko05532772021-06-03 12:12:38 +0200128 if (print_clb) {
129 print_clb(NULL, (NC_VERB_LEVEL)lvl, msg);
130 } else if (depr_print_clb) {
131 depr_print_clb((NC_VERB_LEVEL)lvl, msg);
132 }
Michal Vaskofea54dc2016-02-17 13:12:16 +0100133}
134
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200135API void
Michal Vasko206d3b12015-12-04 11:08:42 +0100136nc_set_print_clb(void (*clb)(NC_VERB_LEVEL, const char *))
137{
Michal Vasko05532772021-06-03 12:12:38 +0200138 print_clb = NULL;
139 depr_print_clb = clb;
140 ly_set_log_clb(nc_ly_log_clb, 1);
141}
142
143API void
144nc_set_print_clb_session(void (*clb)(const struct nc_session *, NC_VERB_LEVEL, const char *))
145{
Michal Vasko206d3b12015-12-04 11:08:42 +0100146 print_clb = clb;
Michal Vasko05532772021-06-03 12:12:38 +0200147 depr_print_clb = NULL;
Michal Vasko6d8a9722020-02-10 14:56:40 +0100148 ly_set_log_clb(nc_ly_log_clb, 1);
Michal Vasko206d3b12015-12-04 11:08:42 +0100149}