mirror of https://github.com/pvnis/srsRAN_4G.git
Update srslog to latest version.
parent
b0a7506a8a
commit
98a2c868b5
@ -1,87 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* \section COPYRIGHT
|
|
||||||
*
|
|
||||||
* Copyright 2013-2020 Software Radio Systems Limited
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the distribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SRSLOG_FORMATTER_H
|
|
||||||
#define SRSLOG_FORMATTER_H
|
|
||||||
|
|
||||||
#include "srslte/srslog/bundled/fmt/chrono.h"
|
|
||||||
#include "srslte/srslog/bundled/fmt/ranges.h"
|
|
||||||
#include "srslte/srslog/detail/log_entry.h"
|
|
||||||
|
|
||||||
namespace srslog {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
/// Formats into a hex dump a range of elements, storing the result in the input
|
|
||||||
/// buffer.
|
|
||||||
inline void format_hex_dump(const std::vector<uint8_t>& v,
|
|
||||||
fmt::memory_buffer& buffer)
|
|
||||||
{
|
|
||||||
if (v.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t elements_per_line = 16;
|
|
||||||
|
|
||||||
for (auto i = v.cbegin(), e = v.cend(); i != e;) {
|
|
||||||
auto num_elements =
|
|
||||||
std::min<size_t>(elements_per_line, std::distance(i, e));
|
|
||||||
|
|
||||||
fmt::format_to(buffer,
|
|
||||||
" {:04x}: {:02x}\n",
|
|
||||||
std::distance(v.cbegin(), i),
|
|
||||||
fmt::join(i, i + num_elements, " "));
|
|
||||||
|
|
||||||
std::advance(i, num_elements);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// Formats to text all the fields of a log entry,
|
|
||||||
inline std::string format_log_entry_to_text(detail::log_entry&& entry)
|
|
||||||
{
|
|
||||||
fmt::memory_buffer buffer;
|
|
||||||
|
|
||||||
// Time stamp data preparation.
|
|
||||||
std::tm current_time =
|
|
||||||
fmt::gmtime(std::chrono::high_resolution_clock::to_time_t(entry.tp));
|
|
||||||
auto us_fraction = std::chrono::duration_cast<std::chrono::microseconds>(
|
|
||||||
entry.tp.time_since_epoch())
|
|
||||||
.count() %
|
|
||||||
1000000u;
|
|
||||||
fmt::format_to(buffer, "{:%H:%M:%S}.{:06} ", current_time, us_fraction);
|
|
||||||
|
|
||||||
// Format optional fields if present.
|
|
||||||
if (!entry.log_name.empty()) {
|
|
||||||
fmt::format_to(buffer, "[{: <4.4}] ", entry.log_name);
|
|
||||||
}
|
|
||||||
if (entry.log_tag != '\0') {
|
|
||||||
fmt::format_to(buffer, "[{}] ", entry.log_tag);
|
|
||||||
}
|
|
||||||
if (entry.context.enabled) {
|
|
||||||
fmt::format_to(buffer, "[{:5}] ", entry.context.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Message formatting.
|
|
||||||
fmt::format_to(
|
|
||||||
buffer, "{}\n", fmt::vsprintf(entry.fmtstring, std::move(entry.store)));
|
|
||||||
|
|
||||||
// Optional hex dump formatting.
|
|
||||||
detail::format_hex_dump(entry.hex_dump, buffer);
|
|
||||||
|
|
||||||
return fmt::to_string(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace srslog
|
|
||||||
|
|
||||||
#endif // SRSLOG_FORMATTER_H
|
|
@ -1,114 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* \section COPYRIGHT
|
|
||||||
*
|
|
||||||
* Copyright 2013-2020 Software Radio Systems Limited
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the distribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SRSLOG_SINK_REPOSITORY_H
|
|
||||||
#define SRSLOG_SINK_REPOSITORY_H
|
|
||||||
|
|
||||||
#include "object_repository.h"
|
|
||||||
#include "sinks/stream_sink.h"
|
|
||||||
|
|
||||||
namespace srslog {
|
|
||||||
|
|
||||||
/// The sink repository stores sink instances associated to an id. Both stdout
|
|
||||||
/// and stderr stream sinks are created on construction so they accessible
|
|
||||||
/// without the need of creating them previously.
|
|
||||||
/// NOTE: Thread safe class.
|
|
||||||
class sink_repository
|
|
||||||
{
|
|
||||||
/// Identifiers for stdout and stderr sinks.
|
|
||||||
static constexpr char stdout_id[] = "stdout#";
|
|
||||||
static constexpr char stderr_id[] = "stderr#";
|
|
||||||
|
|
||||||
object_repository<std::string, std::unique_ptr<sink> > repo;
|
|
||||||
|
|
||||||
public:
|
|
||||||
sink_repository()
|
|
||||||
{
|
|
||||||
//:TODO: GCC5 or lower versions emits an error if we use the new() expression directly, use redundant
|
|
||||||
//piecewise_construct instead.
|
|
||||||
repo.emplace(std::piecewise_construct,
|
|
||||||
std::forward_as_tuple(stdout_id),
|
|
||||||
std::forward_as_tuple(new stream_sink(sink_stream_type::stdout)));
|
|
||||||
repo.emplace(std::piecewise_construct,
|
|
||||||
std::forward_as_tuple(stderr_id),
|
|
||||||
std::forward_as_tuple(new stream_sink(sink_stream_type::stderr)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the instance of the sink that writes to stdout.
|
|
||||||
sink& get_stdout_sink()
|
|
||||||
{
|
|
||||||
auto s = repo.find(stdout_id);
|
|
||||||
assert(s && "stdout sink should always exist");
|
|
||||||
return *(s->get());
|
|
||||||
}
|
|
||||||
const sink& get_stdout_sink() const
|
|
||||||
{
|
|
||||||
const auto s = repo.find(stdout_id);
|
|
||||||
assert(s && "stdout sink should always exist");
|
|
||||||
return *(s->get());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the instance of the sink that writes to stderr.
|
|
||||||
sink& get_stderr_sink()
|
|
||||||
{
|
|
||||||
auto s = repo.find(stderr_id);
|
|
||||||
assert(s && "stderr sink should always exist");
|
|
||||||
return *(s->get());
|
|
||||||
}
|
|
||||||
const sink& get_stderr_sink() const
|
|
||||||
{
|
|
||||||
const auto s = repo.find(stderr_id);
|
|
||||||
assert(s && "stderr sink should always exist");
|
|
||||||
return *(s->get());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds a sink with the specified id in the repository. Returns a pointer to
|
|
||||||
/// the sink, otherwise nullptr if not found.
|
|
||||||
sink* find(const std::string& id)
|
|
||||||
{
|
|
||||||
auto p = repo.find(id);
|
|
||||||
return (p) ? p->get() : nullptr;
|
|
||||||
}
|
|
||||||
const sink* find(const std::string& id) const
|
|
||||||
{
|
|
||||||
const auto p = repo.find(id);
|
|
||||||
return (p) ? p->get() : nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an instance of a sink specified by the input arguments.
|
|
||||||
template <typename... Args>
|
|
||||||
sink& fetch_sink(Args&&... args)
|
|
||||||
{
|
|
||||||
return *repo.emplace(std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a copy of the list of registered sinks.
|
|
||||||
std::vector<sink*> contents() const
|
|
||||||
{
|
|
||||||
auto repo_contents = repo.contents();
|
|
||||||
|
|
||||||
std::vector<sink*> data;
|
|
||||||
data.reserve(repo_contents.size());
|
|
||||||
for (const auto& s : repo_contents) {
|
|
||||||
data.push_back(s->get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr char sink_repository::stdout_id[];
|
|
||||||
constexpr char sink_repository::stderr_id[];
|
|
||||||
|
|
||||||
} // namespace srslog
|
|
||||||
|
|
||||||
#endif // SRSLOG_SINK_REPOSITORY_H
|
|
@ -1,112 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
* \section COPYRIGHT
|
|
||||||
*
|
|
||||||
* Copyright 2013-2020 Software Radio Systems Limited
|
|
||||||
*
|
|
||||||
* By using this file, you agree to the terms and conditions set
|
|
||||||
* forth in the LICENSE file which can be found at the top level of
|
|
||||||
* the distribution.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "src/srslog/formatter.h"
|
|
||||||
#include "testing_helpers.h"
|
|
||||||
#include <numeric>
|
|
||||||
|
|
||||||
using namespace srslog;
|
|
||||||
|
|
||||||
/// Helper to build a log entry.
|
|
||||||
static detail::log_entry build_log_entry()
|
|
||||||
{
|
|
||||||
// Create a time point 50000us from epoch.
|
|
||||||
using tp_ty = std::chrono::time_point<std::chrono::high_resolution_clock>;
|
|
||||||
tp_ty tp(std::chrono::microseconds(50000));
|
|
||||||
|
|
||||||
fmt::dynamic_format_arg_store<fmt::printf_context> store;
|
|
||||||
store.push_back(88);
|
|
||||||
|
|
||||||
return {nullptr, tp, {10, true}, "Text %d", std::move(store), "ABC", 'Z'};
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool when_fully_filled_log_entry_then_result_everything_is_formatted()
|
|
||||||
{
|
|
||||||
std::string result = format_log_entry_to_text(build_log_entry());
|
|
||||||
std::string expected = "00:00:00.050000 [ABC ] [Z] [ 10] Text 88\n";
|
|
||||||
|
|
||||||
ASSERT_EQ(result, expected);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool when_log_entry_without_name_is_passed_then_name_is_not_formatted()
|
|
||||||
{
|
|
||||||
auto entry = build_log_entry();
|
|
||||||
entry.log_name = "";
|
|
||||||
|
|
||||||
std::string result = format_log_entry_to_text(std::move(entry));
|
|
||||||
std::string expected = "00:00:00.050000 [Z] [ 10] Text 88\n";
|
|
||||||
|
|
||||||
ASSERT_EQ(result, expected);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool when_log_entry_without_tag_is_passed_then_tag_is_not_formatted()
|
|
||||||
{
|
|
||||||
auto entry = build_log_entry();
|
|
||||||
entry.log_tag = '\0';
|
|
||||||
|
|
||||||
std::string result = format_log_entry_to_text(std::move(entry));
|
|
||||||
std::string expected = "00:00:00.050000 [ABC ] [ 10] Text 88\n";
|
|
||||||
|
|
||||||
ASSERT_EQ(result, expected);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
when_log_entry_without_context_is_passed_then_context_is_not_formatted()
|
|
||||||
{
|
|
||||||
auto entry = build_log_entry();
|
|
||||||
entry.context.enabled = false;
|
|
||||||
|
|
||||||
std::string result = format_log_entry_to_text(std::move(entry));
|
|
||||||
std::string expected = "00:00:00.050000 [ABC ] [Z] Text 88\n";
|
|
||||||
|
|
||||||
ASSERT_EQ(result, expected);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool when_log_entry_with_hex_dump_is_passed_then_hex_dump_is_formatted()
|
|
||||||
{
|
|
||||||
auto entry = build_log_entry();
|
|
||||||
entry.hex_dump.resize(20);
|
|
||||||
std::iota(entry.hex_dump.begin(), entry.hex_dump.end(), 0);
|
|
||||||
|
|
||||||
std::string result = format_log_entry_to_text(std::move(entry));
|
|
||||||
std::string expected =
|
|
||||||
"00:00:00.050000 [ABC ] [Z] [ 10] Text 88\n"
|
|
||||||
" 0000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n"
|
|
||||||
" 0010: 10 11 12 13\n";
|
|
||||||
|
|
||||||
ASSERT_EQ(result, expected);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
TEST_FUNCTION(
|
|
||||||
when_fully_filled_log_entry_then_result_everything_is_formatted);
|
|
||||||
TEST_FUNCTION(
|
|
||||||
when_log_entry_without_name_is_passed_then_name_is_not_formatted);
|
|
||||||
TEST_FUNCTION(when_log_entry_without_tag_is_passed_then_tag_is_not_formatted);
|
|
||||||
TEST_FUNCTION(
|
|
||||||
when_log_entry_without_context_is_passed_then_context_is_not_formatted);
|
|
||||||
TEST_FUNCTION(
|
|
||||||
when_log_entry_with_hex_dump_is_passed_then_hex_dump_is_formatted);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue