logging.c 14.01 KiB
/*
 * Copyright (c) 2010-2022 Belledonne Communications SARL.
 * This file is part of Liblinphone
 * (see https://gitlab.linphone.org/BC/public/liblinphone).
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <algorithm>
#include <map>
#include <bctoolbox/defs.h>
#include <bctoolbox/logging.h>
#include <belle-sip/object.h>
#include <mediastreamer2/mscommon.h>
#include "linphone/logging.h"
#include "c-wrapper/c-wrapper.h"
#include "logging-private.h"
struct _LinphoneLoggingService {
	belle_sip_object_t base;
	LinphoneLoggingServiceCbs *cbs; // Deprecated, use a list of Cbs instead
	bctbx_list_t *callbacks;
	bctbx_log_handler_t *log_handler;
	char *domain;
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLoggingService);
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneLoggingService);
struct _LinphoneLoggingServiceCbs {
	belle_sip_object_t base;
	void *user_data;
	LinphoneLoggingServiceCbsLogMessageWrittenCb message_event_cb;
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneLoggingServiceCbs);
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneLoggingServiceCbs);
static LinphoneLoggingServiceCbs *_linphone_logging_service_cbs_new(void);
// Use a thread local variable so if two different threads are printing a log at the same time, it won't be a race
// condition on the currentCbs causing it to be set to null by one thread while the second one is in the log callback
// and that will either cause a crash on the worst case scenario or cause the log to be lost on the best case scenario.
static thread_local LinphoneLoggingServiceCbs *currentCbs = NULL;
static LinphoneLoggingService *_linphone_logging_service_instance = NULL;
static std::map<LinphoneLogLevel, BctbxLogLevel> _linphone_log_level_to_bctbx_log_level_map = {
    {LinphoneLogLevelDebug, BCTBX_LOG_DEBUG},     {LinphoneLogLevelTrace, BCTBX_LOG_TRACE},
    {LinphoneLogLevelMessage, BCTBX_LOG_MESSAGE}, {LinphoneLogLevelWarning, BCTBX_LOG_WARNING},
    {LinphoneLogLevelError, BCTBX_LOG_ERROR},     {LinphoneLogLevelFatal, BCTBX_LOG_FATAL}};
LinphoneLogLevel _bctbx_log_level_to_linphone_log_level(BctbxLogLevel level) {
	auto &tmap = _linphone_log_level_to_bctbx_log_level_map;
	auto predicate = [level](const std::pair<LinphoneLogLevel, BctbxLogLevel> &tuple) -> bool {