blob: 8838ec2e238842f8ef1b018bbd9eeb195e89a8c6 [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
Michal Vaskoba9f3582023-02-22 10:26:32 +010016#define _GNU_SOURCE /* pthread_rwlock_t */
17
Radek Krejci5fe60cc2015-09-01 17:14:39 +020018#include <stdarg.h>
Radek Krejci5fe60cc2015-09-01 17:14:39 +020019#include <stdio.h>
roman3f9b65c2023-06-05 14:26:58 +020020#include <stdlib.h>
Radek Krejci5fe60cc2015-09-01 17:14:39 +020021
Michal Vaskoa601f5c2015-12-08 14:33:03 +010022#include <libyang/libyang.h>
23
roman2eab4742023-06-06 10:00:26 +020024#ifdef NC_ENABLED_SSH_TLS
Michal Vaskob078fee2016-09-29 11:30:31 +020025 #include <libssh/libssh.h>
roman2eab4742023-06-06 10:00:26 +020026#endif /* NC_ENABLED_SSH_TLS */
Michal Vaskob078fee2016-09-29 11:30:31 +020027
Michal Vasko7a20d2e2021-05-19 16:40:23 +020028#include "compat.h"
roman3f9b65c2023-06-05 14:26:58 +020029#include "config.h"
Michal Vaskob078fee2016-09-29 11:30:31 +020030#include "log.h"
roman3f9b65c2023-06-05 14:26:58 +020031#include "session_p.h"
Radek Krejci5fe60cc2015-09-01 17:14:39 +020032
33/**
34 * @brief libnetconf verbose level variable
35 */
Václav Kubernáta4474cf2022-01-17 12:37:22 +010036ATOMIC_T verbose_level = 0;
Radek Krejci5fe60cc2015-09-01 17:14:39 +020037
Michal Vasko05532772021-06-03 12:12:38 +020038void (*depr_print_clb)(NC_VERB_LEVEL level, const char *msg);
39void (*print_clb)(const struct nc_session *session, NC_VERB_LEVEL level, const char *msg);
Michal Vasko206d3b12015-12-04 11:08:42 +010040
Radek Krejci5fe60cc2015-09-01 17:14:39 +020041API void
42nc_verbosity(NC_VERB_LEVEL level)
43{
Václav Kubernáta4474cf2022-01-17 12:37:22 +010044 ATOMIC_STORE_RELAXED(verbose_level, level);
Michal Vasko77367452021-02-16 16:32:18 +010045 ly_log_level((LY_LOG_LEVEL)level);
Radek Krejci5fe60cc2015-09-01 17:14:39 +020046}
47
48struct {
49 NC_VERB_LEVEL level;
50 const char *label;
51} verb[] = {
bhartb186eba2018-11-12 15:35:09 -060052 {NC_VERB_ERROR, "[ERR]"},
53 {NC_VERB_WARNING, "[WRN]"},
54 {NC_VERB_VERBOSE, "[INF]"},
Michal Vasko2733aad2020-04-16 09:01:52 +020055 {NC_VERB_DEBUG, "[DBG]"},
56 {NC_VERB_DEBUG_LOWLVL, "[DBL]"}
Radek Krejci5fe60cc2015-09-01 17:14:39 +020057};
58
roman2eab4742023-06-06 10:00:26 +020059#ifdef NC_ENABLED_SSH_TLS
Michal Vaskob078fee2016-09-29 11:30:31 +020060
61API void
62nc_libssh_thread_verbosity(int level)
63{
64 ssh_set_log_level(level);
65}
66
roman2eab4742023-06-06 10:00:26 +020067#endif /* NC_ENABLED_SSH_TLS */
Michal Vaskob078fee2016-09-29 11:30:31 +020068
Radek Krejci5fe60cc2015-09-01 17:14:39 +020069static void
Michal Vasko05532772021-06-03 12:12:38 +020070prv_vprintf(const struct nc_session *session, NC_VERB_LEVEL level, const char *format, va_list args)
Radek Krejci5fe60cc2015-09-01 17:14:39 +020071{
Michal Vaskofe5e8c92021-04-14 08:23:12 +020072#define PRV_MSG_INIT_SIZE 256
73 va_list args2;
74 char *prv_msg;
75 void *mem;
76 int req_len;
Radek Krejci5fe60cc2015-09-01 17:14:39 +020077
Michal Vaskofe5e8c92021-04-14 08:23:12 +020078 prv_msg = malloc(PRV_MSG_INIT_SIZE);
79 if (!prv_msg) {
80 return;
81 }
82
83 va_copy(args2, args);
84
85 req_len = vsnprintf(prv_msg, PRV_MSG_INIT_SIZE - 1, format, args);
86 if (req_len == -1) {
87 goto cleanup;
88 } else if (req_len >= PRV_MSG_INIT_SIZE - 1) {
89 /* the length is not enough */
90 ++req_len;
91 mem = realloc(prv_msg, req_len);
92 if (!mem) {
93 goto cleanup;
94 }
95 prv_msg = mem;
96
97 /* now print the full message */
98 req_len = vsnprintf(prv_msg, req_len, format, args2);
99 if (req_len == -1) {
100 goto cleanup;
101 }
102 }
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200103
Michal Vasko206d3b12015-12-04 11:08:42 +0100104 if (print_clb) {
Michal Vasko05532772021-06-03 12:12:38 +0200105 print_clb(session, level, prv_msg);
106 } else if (depr_print_clb) {
107 depr_print_clb(level, prv_msg);
108 } else if (session && session->id) {
109 fprintf(stderr, "Session %u %s: %s\n", session->id, verb[level].label, prv_msg);
Michal Vasko206d3b12015-12-04 11:08:42 +0100110 } else {
111 fprintf(stderr, "%s: %s\n", verb[level].label, prv_msg);
112 }
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200113
Michal Vaskofe5e8c92021-04-14 08:23:12 +0200114cleanup:
115 free(prv_msg);
116#undef PRV_MSG_INIT_SIZE
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200117}
118
119void
Michal Vasko05532772021-06-03 12:12:38 +0200120prv_printf(const struct nc_session *session, NC_VERB_LEVEL level, const char *format, ...)
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200121{
122 va_list ap;
123
124 va_start(ap, format);
Michal Vasko05532772021-06-03 12:12:38 +0200125 prv_vprintf(session, level, format, ap);
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200126 va_end(ap);
127}
128
Michal Vaskofea54dc2016-02-17 13:12:16 +0100129static void
Michal Vasko58791da2024-02-26 13:52:59 +0100130nc_ly_log_clb(LY_LOG_LEVEL lvl, const char *msg, const char *UNUSED(data_path), const char *UNUSED(schema_path),
131 uint64_t UNUSED(line))
Michal Vaskofea54dc2016-02-17 13:12:16 +0100132{
Michal Vasko05532772021-06-03 12:12:38 +0200133 if (print_clb) {
134 print_clb(NULL, (NC_VERB_LEVEL)lvl, msg);
135 } else if (depr_print_clb) {
136 depr_print_clb((NC_VERB_LEVEL)lvl, msg);
137 }
Michal Vaskofea54dc2016-02-17 13:12:16 +0100138}
139
Radek Krejci5fe60cc2015-09-01 17:14:39 +0200140API void
Michal Vasko05532772021-06-03 12:12:38 +0200141nc_set_print_clb_session(void (*clb)(const struct nc_session *, NC_VERB_LEVEL, const char *))
142{
Michal Vasko206d3b12015-12-04 11:08:42 +0100143 print_clb = clb;
Michal Vasko05532772021-06-03 12:12:38 +0200144 depr_print_clb = NULL;
Michal Vasko58791da2024-02-26 13:52:59 +0100145 ly_set_log_clb(nc_ly_log_clb);
Michal Vasko206d3b12015-12-04 11:08:42 +0100146}