2020-11-30 11:43:50 -08:00
|
|
|
/**
|
2022-04-29 00:28:44 -07:00
|
|
|
* Copyright 2013-2022 Software Radio Systems Limited
|
2020-07-22 07:04:18 -07:00
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* This file is part of srsRAN.
|
2020-07-22 07:04:18 -07:00
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* srsRAN is free software: you can redistribute it and/or modify
|
2021-03-28 14:12:42 -07:00
|
|
|
* 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.
|
|
|
|
*
|
2021-04-22 01:59:40 -07:00
|
|
|
* srsRAN is distributed in the hope that it will be useful,
|
2021-03-28 14:12:42 -07:00
|
|
|
* 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.
|
2020-07-22 07:04:18 -07:00
|
|
|
*
|
2021-03-28 14:12:42 -07:00
|
|
|
* A copy of the GNU Affero General Public License can be found in
|
|
|
|
* the LICENSE file in the top-level directory of this distribution
|
|
|
|
* and at http://www.gnu.org/licenses/.
|
2020-07-22 07:04:18 -07:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2021-03-19 03:45:56 -07:00
|
|
|
#include "srsran/srslog/srslog.h"
|
2020-12-10 09:10:49 -08:00
|
|
|
#include "formatters/json_formatter.h"
|
2020-07-22 07:04:18 -07:00
|
|
|
#include "sinks/file_sink.h"
|
2021-07-09 12:03:02 -07:00
|
|
|
#include "sinks/syslog_sink.h"
|
2020-07-22 07:04:18 -07:00
|
|
|
#include "srslog_instance.h"
|
|
|
|
|
|
|
|
using namespace srslog;
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
/// Returns a copy of the input string with any occurrences of the '#' character
|
|
|
|
/// removed.
|
|
|
|
static std::string remove_sharp_chars(const std::string& s)
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2020-09-30 06:52:42 -07:00
|
|
|
std::string result(s);
|
|
|
|
result.erase(std::remove(result.begin(), result.end(), '#'), result.end());
|
|
|
|
return result;
|
|
|
|
}
|
2020-07-22 07:04:18 -07:00
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
/// Generic argument function that fetches a log channel from the repository.
|
|
|
|
template <typename... Args>
|
2021-04-13 05:01:55 -07:00
|
|
|
static log_channel& fetch_log_channel_helper(const std::string& id, Args&&... args)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
|
|
|
return srslog_instance::get().get_channel_repo().emplace(
|
2021-04-13 05:01:55 -07:00
|
|
|
std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(id, std::forward<Args>(args)...));
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
///
|
|
|
|
/// Log channel management function implementations.
|
|
|
|
///
|
|
|
|
|
2020-07-22 07:04:18 -07:00
|
|
|
log_channel* srslog::find_log_channel(const std::string& id)
|
|
|
|
{
|
2020-09-30 06:52:42 -07:00
|
|
|
return srslog_instance::get().get_channel_repo().find(id);
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
log_channel& srslog::fetch_log_channel(const std::string& id)
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2020-09-30 06:52:42 -07:00
|
|
|
assert(!id.empty() && "Empty id string");
|
|
|
|
|
2020-12-10 09:10:49 -08:00
|
|
|
std::string clean_id = remove_sharp_chars(id);
|
2021-04-13 05:01:55 -07:00
|
|
|
|
|
|
|
if (auto* c = find_log_channel(clean_id)) {
|
|
|
|
return *c;
|
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
srslog_instance& instance = srslog_instance::get();
|
2021-04-13 05:01:55 -07:00
|
|
|
return fetch_log_channel_helper(clean_id, instance.get_default_sink(), instance.get_backend());
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
log_channel& srslog::fetch_log_channel(const std::string& id, sink& s, log_channel_config config)
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2020-09-30 06:52:42 -07:00
|
|
|
assert(!id.empty() && "Empty id string");
|
2020-07-22 07:04:18 -07:00
|
|
|
|
2020-12-10 09:10:49 -08:00
|
|
|
std::string clean_id = remove_sharp_chars(id);
|
2021-04-13 05:01:55 -07:00
|
|
|
|
|
|
|
if (auto* c = find_log_channel(clean_id)) {
|
|
|
|
return *c;
|
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
srslog_instance& instance = srslog_instance::get();
|
2021-04-13 05:01:55 -07:00
|
|
|
return fetch_log_channel_helper(clean_id, s, instance.get_backend(), std::move(config));
|
2020-12-10 09:10:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Formatter management functions.
|
|
|
|
///
|
|
|
|
|
|
|
|
void srslog::set_default_log_formatter(std::unique_ptr<log_formatter> f)
|
|
|
|
{
|
|
|
|
srslog_instance::get().set_default_formatter(std::move(f));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<log_formatter> srslog::get_default_log_formatter()
|
|
|
|
{
|
|
|
|
return srslog_instance::get().get_default_formatter();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<log_formatter> srslog::create_text_formatter()
|
|
|
|
{
|
|
|
|
return std::unique_ptr<log_formatter>(new text_formatter);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<log_formatter> srslog::create_json_formatter()
|
|
|
|
{
|
|
|
|
return std::unique_ptr<log_formatter>(new json_formatter);
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
///
|
|
|
|
/// Sink management function implementations.
|
|
|
|
///
|
|
|
|
|
|
|
|
void srslog::set_default_sink(sink& s)
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2020-09-30 06:52:42 -07:00
|
|
|
srslog_instance::get().set_default_sink(s);
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
sink& srslog::get_default_sink()
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2020-09-30 06:52:42 -07:00
|
|
|
return srslog_instance::get().get_default_sink();
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
sink* srslog::find_sink(const std::string& id)
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2020-12-10 09:10:49 -08:00
|
|
|
auto ptr = srslog_instance::get().get_sink_repo().find(id);
|
|
|
|
return (ptr) ? ptr->get() : nullptr;
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
sink& srslog::fetch_stdout_sink(const std::string& id, std::unique_ptr<log_formatter> f)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
2020-12-10 09:10:49 -08:00
|
|
|
assert(!id.empty() && "Empty id string");
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
if (auto* s = find_sink(id)) {
|
|
|
|
return *s;
|
|
|
|
}
|
|
|
|
|
2020-12-10 09:10:49 -08:00
|
|
|
auto& s = srslog_instance::get().get_sink_repo().emplace(
|
|
|
|
std::piecewise_construct,
|
|
|
|
std::forward_as_tuple(id),
|
2021-04-13 05:01:55 -07:00
|
|
|
std::forward_as_tuple(new stream_sink(sink_stream_type::stdout, std::move(f))));
|
2020-12-10 09:10:49 -08:00
|
|
|
|
|
|
|
return *s;
|
2020-09-30 06:52:42 -07:00
|
|
|
}
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
sink& srslog::fetch_stderr_sink(const std::string& id, std::unique_ptr<log_formatter> f)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
2020-12-10 09:10:49 -08:00
|
|
|
assert(!id.empty() && "Empty id string");
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
if (auto* s = find_sink(id)) {
|
|
|
|
return *s;
|
|
|
|
}
|
|
|
|
|
2020-12-10 09:10:49 -08:00
|
|
|
auto& s = srslog_instance::get().get_sink_repo().emplace(
|
|
|
|
std::piecewise_construct,
|
|
|
|
std::forward_as_tuple(id),
|
2021-04-13 05:01:55 -07:00
|
|
|
std::forward_as_tuple(new stream_sink(sink_stream_type::stderr, std::move(f))));
|
2020-12-10 09:10:49 -08:00
|
|
|
|
|
|
|
return *s;
|
2020-09-30 06:52:42 -07:00
|
|
|
}
|
|
|
|
|
2021-09-13 02:08:56 -07:00
|
|
|
sink& srslog::fetch_file_sink(const std::string& path,
|
|
|
|
size_t max_size,
|
|
|
|
bool force_flush,
|
|
|
|
std::unique_ptr<log_formatter> f)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
|
|
|
assert(!path.empty() && "Empty path string");
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
if (auto* s = find_sink(path)) {
|
|
|
|
return *s;
|
|
|
|
}
|
|
|
|
|
2021-04-22 04:50:26 -07:00
|
|
|
//: TODO: GCC5 or lower versions emits an error if we use the new() expression
|
2020-12-10 09:10:49 -08:00
|
|
|
// directly, use redundant piecewise_construct instead.
|
|
|
|
auto& s = srslog_instance::get().get_sink_repo().emplace(
|
|
|
|
std::piecewise_construct,
|
|
|
|
std::forward_as_tuple(path),
|
2021-09-13 02:08:56 -07:00
|
|
|
std::forward_as_tuple(new file_sink(path, max_size, force_flush, std::move(f))));
|
2020-12-10 09:10:49 -08:00
|
|
|
|
|
|
|
return *s;
|
|
|
|
}
|
|
|
|
|
2021-07-09 12:03:02 -07:00
|
|
|
sink& srslog::fetch_syslog_sink(const std::string& preamble_,
|
|
|
|
syslog_local_type log_local_,
|
|
|
|
std::unique_ptr<log_formatter> f)
|
|
|
|
{
|
|
|
|
std::string sink_id = preamble_ + std::to_string(static_cast<int>(log_local_));
|
|
|
|
if (auto* s = find_sink(sink_id)) {
|
|
|
|
return *s;
|
|
|
|
}
|
|
|
|
|
|
|
|
//: TODO: GCC5 or lower versions emits an error if we use the new() expression
|
|
|
|
// directly, use redundant piecewise_construct instead.
|
|
|
|
auto& s = srslog_instance::get().get_sink_repo().emplace(
|
|
|
|
std::piecewise_construct,
|
|
|
|
std::forward_as_tuple(sink_id),
|
|
|
|
std::forward_as_tuple(new syslog_sink(std::move(f), preamble_, log_local_)));
|
|
|
|
|
|
|
|
return *s;
|
|
|
|
}
|
|
|
|
|
2020-12-10 09:10:49 -08:00
|
|
|
bool srslog::install_custom_sink(const std::string& id, std::unique_ptr<sink> s)
|
|
|
|
{
|
|
|
|
assert(!id.empty() && "Empty path string");
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
sink* input_sink = s.get();
|
|
|
|
sink* returned_sink = srslog_instance::get().get_sink_repo().emplace(id, std::move(s)).get();
|
2020-12-10 09:10:49 -08:00
|
|
|
|
|
|
|
// Successful insertion occurs when the returned object is the same one as the
|
|
|
|
// input object.
|
|
|
|
return input_sink == returned_sink;
|
2020-09-30 06:52:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Framework configuration and control function implementations.
|
|
|
|
///
|
|
|
|
|
2021-04-28 01:21:56 -07:00
|
|
|
void srslog::init(backend_priority priority)
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2021-04-28 01:21:56 -07:00
|
|
|
srslog_instance::get().get_backend().start(priority);
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
void srslog::flush()
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2020-09-30 06:52:42 -07:00
|
|
|
srslog_instance& instance = srslog_instance::get();
|
|
|
|
|
|
|
|
// Nothing to do when the backend is not running yet.
|
|
|
|
if (!instance.get_backend().is_running()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The backend will set this shared variable when done.
|
|
|
|
detail::shared_variable<bool> completion_flag(false);
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
auto sink_ptrs = instance.get_sink_repo().contents();
|
2020-12-10 09:10:49 -08:00
|
|
|
std::vector<sink*> sinks;
|
|
|
|
sinks.reserve(sink_ptrs.size());
|
|
|
|
for (const auto& s : sink_ptrs) {
|
|
|
|
sinks.push_back(s->get());
|
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
detail::log_entry cmd;
|
2021-03-22 02:46:32 -07:00
|
|
|
cmd.metadata.store = nullptr;
|
2021-04-13 05:01:55 -07:00
|
|
|
cmd.flush_cmd =
|
|
|
|
std::unique_ptr<detail::flush_backend_cmd>(new detail::flush_backend_cmd{completion_flag, std::move(sinks)});
|
2020-09-30 06:52:42 -07:00
|
|
|
|
2021-01-28 03:17:18 -08:00
|
|
|
// Make sure the flush command gets into the backend, otherwise we will be
|
|
|
|
// stuck waiting forever for the command to succeed.
|
|
|
|
while (!instance.get_backend().push(std::move(cmd))) {
|
|
|
|
}
|
2020-09-30 06:52:42 -07:00
|
|
|
|
|
|
|
// Block the caller thread until we are signaled that the flush is completed.
|
|
|
|
while (!completion_flag) {
|
|
|
|
std::this_thread::sleep_for(std::chrono::microseconds(100));
|
|
|
|
}
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
void srslog::set_error_handler(error_handler handler)
|
|
|
|
{
|
|
|
|
srslog_instance::get().set_error_handler(std::move(handler));
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Logger management function implementations.
|
|
|
|
///
|
|
|
|
|
2020-07-22 07:04:18 -07:00
|
|
|
detail::any* srslog::detail::find_logger(const std::string& id)
|
|
|
|
{
|
|
|
|
return srslog_instance::get().get_logger_repo().find(id);
|
|
|
|
}
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
detail::any* srslog::detail::fetch_logger(const std::string& id, detail::any&& logger)
|
2020-07-22 07:04:18 -07:00
|
|
|
{
|
2020-09-30 06:52:42 -07:00
|
|
|
assert(!id.empty() && "Empty id string");
|
2021-04-13 05:01:55 -07:00
|
|
|
return &srslog_instance::get().get_logger_repo().emplace(id, std::move(logger));
|
2020-09-30 06:52:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Builds a logger name out of the id and tag.
|
|
|
|
static std::string build_logger_name(const std::string& id, char tag)
|
|
|
|
{
|
|
|
|
return fmt::format("{}#{}", id, tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Fetches a logger with all its log channels.
|
2021-04-13 05:01:55 -07:00
|
|
|
static basic_logger& fetch_basic_logger_helper(const std::string& id, sink& s, bool should_print_context)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
|
|
|
static constexpr char basic_logger_chan_tags[] = {'E', 'W', 'I', 'D'};
|
|
|
|
|
|
|
|
srslog_instance& instance = srslog_instance::get();
|
|
|
|
|
|
|
|
// User created log channels cannot have ids with a # character, encode the
|
|
|
|
// ids here with a # to ensure all channels are unique.
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
log_channel& error =
|
|
|
|
fetch_log_channel_helper(build_logger_name(id, basic_logger_chan_tags[0]),
|
|
|
|
s,
|
|
|
|
instance.get_backend(),
|
|
|
|
log_channel_config{id, basic_logger_chan_tags[0], should_print_context});
|
|
|
|
log_channel& warning =
|
|
|
|
fetch_log_channel_helper(build_logger_name(id, basic_logger_chan_tags[1]),
|
|
|
|
s,
|
|
|
|
instance.get_backend(),
|
|
|
|
log_channel_config{id, basic_logger_chan_tags[1], should_print_context});
|
|
|
|
log_channel& info = fetch_log_channel_helper(build_logger_name(id, basic_logger_chan_tags[2]),
|
|
|
|
s,
|
|
|
|
instance.get_backend(),
|
|
|
|
log_channel_config{id, basic_logger_chan_tags[2], should_print_context});
|
|
|
|
log_channel& debug =
|
|
|
|
fetch_log_channel_helper(build_logger_name(id, basic_logger_chan_tags[3]),
|
|
|
|
s,
|
|
|
|
instance.get_backend(),
|
|
|
|
log_channel_config{id, basic_logger_chan_tags[3], should_print_context});
|
2020-09-30 06:52:42 -07:00
|
|
|
|
|
|
|
return fetch_logger<basic_logger>(id, error, warning, info, debug);
|
|
|
|
}
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
basic_logger& srslog::fetch_basic_logger(const std::string& id, bool should_print_context)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
|
|
|
assert(!id.empty() && "Empty id string");
|
2021-04-13 05:01:55 -07:00
|
|
|
|
|
|
|
if (auto* logger = find_logger<basic_logger>(id)) {
|
|
|
|
return *logger;
|
|
|
|
}
|
|
|
|
|
|
|
|
return fetch_basic_logger_helper(id, srslog_instance::get().get_default_sink(), should_print_context);
|
2020-09-30 06:52:42 -07:00
|
|
|
}
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
basic_logger& srslog::fetch_basic_logger(const std::string& id, sink& s, bool should_print_context)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
|
|
|
assert(!id.empty() && "Empty id string");
|
2021-04-13 05:01:55 -07:00
|
|
|
|
|
|
|
if (auto* logger = find_logger<basic_logger>(id)) {
|
|
|
|
return *logger;
|
|
|
|
}
|
|
|
|
|
2020-09-30 06:52:42 -07:00
|
|
|
return fetch_basic_logger_helper(id, s, should_print_context);
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// Deprecated functions to be removed.
|
|
|
|
///
|
|
|
|
|
|
|
|
/// Creates and registers a log channel. Returns a pointer to the newly created
|
|
|
|
/// channel on success, otherwise nullptr.
|
2021-04-13 05:01:55 -07:00
|
|
|
static log_channel* create_and_register_log_channel(const std::string& id, sink& s)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
|
|
|
assert(!id.empty() && "Empty id string");
|
|
|
|
|
|
|
|
srslog_instance& instance = srslog_instance::get();
|
|
|
|
|
|
|
|
auto& p = instance.get_channel_repo().emplace(
|
2021-04-13 05:01:55 -07:00
|
|
|
std::piecewise_construct, std::forward_as_tuple(id), std::forward_as_tuple(id, s, instance.get_backend()));
|
2020-09-30 06:52:42 -07:00
|
|
|
|
|
|
|
return &p;
|
|
|
|
}
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
static log_channel* create_and_register_log_channel(const std::string& id, log_channel_config config, sink& s)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
|
|
|
assert(!id.empty() && "Empty id string");
|
|
|
|
|
|
|
|
srslog_instance& instance = srslog_instance::get();
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
auto& p =
|
|
|
|
instance.get_channel_repo().emplace(std::piecewise_construct,
|
|
|
|
std::forward_as_tuple(id),
|
|
|
|
std::forward_as_tuple(id, s, instance.get_backend(), std::move(config)));
|
2020-09-30 06:52:42 -07:00
|
|
|
|
|
|
|
return &p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns true if the input string contains a sharp character, otherwise
|
|
|
|
/// returns false.
|
|
|
|
static bool contains_sharp_char(const std::string& s)
|
|
|
|
{
|
|
|
|
return s.find('#') != std::string::npos;
|
|
|
|
}
|
|
|
|
|
|
|
|
log_channel* srslog::create_log_channel(const std::string& id, sink& s)
|
|
|
|
{
|
|
|
|
if (contains_sharp_char(id)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
return create_and_register_log_channel(id, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
sink* srslog::create_stdout_sink(const std::string& name)
|
|
|
|
{
|
2020-12-10 09:10:49 -08:00
|
|
|
return srslog_instance::get().get_sink_repo().find("stdout")->get();
|
2020-09-30 06:52:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
sink* srslog::create_stderr_sink(const std::string& name)
|
|
|
|
{
|
2020-12-10 09:10:49 -08:00
|
|
|
return srslog_instance::get().get_sink_repo().find("stderr")->get();
|
2020-09-30 06:52:42 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
sink* srslog::create_file_sink(const std::string& path, size_t max_size)
|
|
|
|
{
|
2021-04-22 04:50:26 -07:00
|
|
|
//: TODO: GCC5 or lower versions emits an error if we use the new() expression
|
2020-12-10 09:10:49 -08:00
|
|
|
// directly, use redundant piecewise_construct instead.
|
|
|
|
return srslog_instance::get()
|
|
|
|
.get_sink_repo()
|
|
|
|
.emplace(std::piecewise_construct,
|
|
|
|
std::forward_as_tuple(path),
|
2021-09-13 02:08:56 -07:00
|
|
|
std::forward_as_tuple(
|
|
|
|
new file_sink(path, max_size, false, std::unique_ptr<log_formatter>(new text_formatter))))
|
2020-12-10 09:10:49 -08:00
|
|
|
.get();
|
2020-09-30 06:52:42 -07:00
|
|
|
}
|
|
|
|
|
2021-04-13 05:01:55 -07:00
|
|
|
basic_logger* srslog::create_basic_logger(const std::string& id, sink& s, bool should_print_context)
|
2020-09-30 06:52:42 -07:00
|
|
|
{
|
|
|
|
assert(!id.empty() && "Empty id string");
|
|
|
|
|
|
|
|
static constexpr char basic_logger_chan_tags[] = {'E', 'W', 'I', 'D'};
|
|
|
|
|
|
|
|
auto& logger_repo = srslog_instance::get().get_logger_repo();
|
|
|
|
|
|
|
|
// Nothing to do when the logger already exists.
|
|
|
|
if (logger_repo.find(id)) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// User created log channels cannot have ids with a # character, encode the
|
|
|
|
// ids here with a # to ensure all channel creations will be successful
|
|
|
|
// without any id clashes.
|
|
|
|
|
|
|
|
log_channel* error = create_and_register_log_channel(
|
2021-04-13 05:01:55 -07:00
|
|
|
build_logger_name(id, basic_logger_chan_tags[0]), {id, basic_logger_chan_tags[0], should_print_context}, s);
|
2020-09-30 06:52:42 -07:00
|
|
|
assert(error && "Could not create channel");
|
|
|
|
log_channel* warning = create_and_register_log_channel(
|
2021-04-13 05:01:55 -07:00
|
|
|
build_logger_name(id, basic_logger_chan_tags[1]), {id, basic_logger_chan_tags[1], should_print_context}, s);
|
2020-09-30 06:52:42 -07:00
|
|
|
assert(warning && "Could not create channel");
|
|
|
|
log_channel* info = create_and_register_log_channel(
|
2021-04-13 05:01:55 -07:00
|
|
|
build_logger_name(id, basic_logger_chan_tags[2]), {id, basic_logger_chan_tags[2], should_print_context}, s);
|
2020-09-30 06:52:42 -07:00
|
|
|
assert(info && "Could not create channel");
|
|
|
|
log_channel* debug = create_and_register_log_channel(
|
2021-04-13 05:01:55 -07:00
|
|
|
build_logger_name(id, basic_logger_chan_tags[3]), {id, basic_logger_chan_tags[3], should_print_context}, s);
|
2020-09-30 06:52:42 -07:00
|
|
|
assert(debug && "Could not create channel");
|
|
|
|
|
|
|
|
return create_logger<basic_logger>(id, *error, *warning, *info, *debug);
|
2020-07-22 07:04:18 -07:00
|
|
|
}
|