1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-13 03:32:22 +00:00
ton/tonlib/tonlib/Logging.cpp
2020-04-10 23:06:01 +04:00

144 lines
4.8 KiB
C++

/*
This file is part of TON Blockchain Library.
TON Blockchain Library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
TON Blockchain Library 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with TON Blockchain Library. If not, see <http://www.gnu.org/licenses/>.
Copyright 2017-2020 Telegram Systems LLP
*/
#include "Logging.h"
#include "utils.h"
#include "auto/tl/tonlib_api.h"
#include "td/utils/FileLog.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
#include "td/utils/misc.h"
#include <atomic>
#include <map>
#include <mutex>
namespace tonlib {
struct LogData {
std::mutex logging_mutex;
td::FileLog file_log;
td::TsLog ts_log{&file_log};
td::NullLog null_log;
};
auto &log_data() {
static LogData data;
return data;
}
#define ADD_TAG(tag) \
{ #tag, &VERBOSITY_NAME(tag) }
static const std::map<td::Slice, int *> log_tags{ADD_TAG(tonlib_query), ADD_TAG(last_block), ADD_TAG(last_config),
ADD_TAG(lite_server)};
#undef ADD_TAG
td::Status Logging::set_current_stream(tonlib_api::object_ptr<tonlib_api::LogStream> stream) {
if (stream == nullptr) {
return td::Status::Error("Log stream must not be empty");
}
std::lock_guard<std::mutex> lock(log_data().logging_mutex);
switch (stream->get_id()) {
case tonlib_api::logStreamDefault::ID:
td::log_interface = td::default_log_interface;
return td::Status::OK();
case tonlib_api::logStreamFile::ID: {
auto file_stream = tonlib_api::move_object_as<tonlib_api::logStreamFile>(stream);
auto max_log_file_size = file_stream->max_file_size_;
if (max_log_file_size <= 0) {
return td::Status::Error("Max log file size should be positive");
}
TRY_STATUS(log_data().file_log.init(file_stream->path_, max_log_file_size));
std::atomic_thread_fence(std::memory_order_release); // better than nothing
td::log_interface = &log_data().ts_log;
return td::Status::OK();
}
case tonlib_api::logStreamEmpty::ID:
td::log_interface = &log_data().null_log;
return td::Status::OK();
default:
UNREACHABLE();
return td::Status::OK();
}
}
td::Result<tonlib_api::object_ptr<tonlib_api::LogStream>> Logging::get_current_stream() {
std::lock_guard<std::mutex> lock(log_data().logging_mutex);
if (td::log_interface == td::default_log_interface) {
return tonlib_api::make_object<tonlib_api::logStreamDefault>();
}
if (td::log_interface == &log_data().null_log) {
return tonlib_api::make_object<tonlib_api::logStreamEmpty>();
}
if (td::log_interface == &log_data().ts_log) {
return tonlib_api::make_object<tonlib_api::logStreamFile>(log_data().file_log.get_path().str(),
log_data().file_log.get_rotate_threshold());
}
return td::Status::Error("Log stream is unrecognized");
}
td::Status Logging::set_verbosity_level(int new_verbosity_level) {
std::lock_guard<std::mutex> lock(log_data().logging_mutex);
if (0 <= new_verbosity_level && new_verbosity_level <= VERBOSITY_NAME(NEVER)) {
SET_VERBOSITY_LEVEL(VERBOSITY_NAME(FATAL) + new_verbosity_level);
return td::Status::OK();
}
return td::Status::Error("Wrong new verbosity level specified");
}
int Logging::get_verbosity_level() {
std::lock_guard<std::mutex> lock(log_data().logging_mutex);
return GET_VERBOSITY_LEVEL();
}
td::vector<td::string> Logging::get_tags() {
return transform(log_tags, [](auto &tag) { return tag.first.str(); });
}
td::Status Logging::set_tag_verbosity_level(td::Slice tag, int new_verbosity_level) {
auto it = log_tags.find(tag);
if (it == log_tags.end()) {
return td::Status::Error("Log tag is not found");
}
std::lock_guard<std::mutex> lock(log_data().logging_mutex);
*it->second = td::clamp(new_verbosity_level, 1, VERBOSITY_NAME(NEVER));
return td::Status::OK();
}
td::Result<int> Logging::get_tag_verbosity_level(td::Slice tag) {
auto it = log_tags.find(tag);
if (it == log_tags.end()) {
return td::Status::Error("Log tag is not found");
}
std::lock_guard<std::mutex> lock(log_data().logging_mutex);
return *it->second;
}
void Logging::add_message(int log_verbosity_level, td::Slice message) {
int VERBOSITY_NAME(client) = td::clamp(log_verbosity_level, 0, VERBOSITY_NAME(NEVER));
VLOG(client) << message;
}
} // namespace tonlib