Added syslog logger

This commit is contained in:
David Rupprecht 2021-07-09 21:03:02 +02:00 committed by David Rupprecht
parent 7b7ecb7983
commit d990db66f6
6 changed files with 204 additions and 0 deletions

View File

@ -31,6 +31,18 @@ enum class backend_priority
very_high
};
/// syslog log local types
enum class syslog_local_type {
local0,
local1,
local2,
local3,
local4,
local5,
local6,
local7,
};
} // namespace srslog
#endif // SRSLOG_SHARED_TYPES_H

View File

@ -184,6 +184,14 @@ sink& fetch_file_sink(const std::string& path,
size_t max_size = 0,
std::unique_ptr<log_formatter> f = get_default_log_formatter());
/// Returns an instance of a sink that writes into syslog
/// preamble: The string prepended to every message, If ident is "", the program name is used.
/// log_local: custom unused facilities that syslog provides which can be used by the user
/// NOTE: Any '#' characters in the path will get removed.
sink& fetch_syslog_sink(const std::string& preamble_ = "",
syslog_local_type log_local_ = syslog_local_type::local0,
std::unique_ptr<log_formatter> f = get_default_log_formatter());
/// Installs a custom user defined sink in the framework getting associated to
/// the specified id. Returns true on success, otherwise false.
/// WARNING: This function is an advanced feature and users should really know

View File

@ -0,0 +1,97 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 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_SYSLOG_SINK_H
#define SRSLOG_SYSLOG_SINK_H
#include "srsran/srslog/shared_types.h"
#include "srsran/srslog/sink.h"
#include <syslog.h>
namespace srslog {
/// This sink implementation writes to syslog.
class syslog_sink : public sink
{
public:
syslog_sink(std::unique_ptr<log_formatter> f,
std::string preamble_ = "",
syslog_local_type log_local_ = syslog_local_type::local0) :
sink(std::move(f))
{
create_syslog(preamble_, syslog_translate(log_local_));
}
syslog_sink(const syslog_sink& other) = delete;
syslog_sink& operator=(const syslog_sink& other) = delete;
detail::error_string write(detail::memory_buffer buffer) override
{
std::string entry(buffer.data(), buffer.size());
if (entry.find("[E]") != std::string::npos) {
syslog(LOG_ERR, "%s", buffer.data());
} else if (entry.find("[W]") != std::string::npos) {
syslog(LOG_WARNING, "%s", buffer.data());
} else if (entry.find("[I]") != std::string::npos) {
syslog(LOG_INFO, "%s", buffer.data());
} else if (entry.find("[D]") != std::string::npos) {
syslog(LOG_DEBUG, "%s", buffer.data());
} else {
syslog(LOG_ERR, "%s", buffer.data());
}
// openlog syslog does not return any value.
return {};
}
detail::error_string flush() override { return {}; }
private:
/// Creates a new syslog
detail::error_string create_syslog(std::string preamble, int log_local)
{
if (preamble == "") {
openlog(NULL, LOG_CONS | LOG_PID | LOG_NDELAY, log_local);
} else {
openlog(preamble.c_str(), LOG_CONS | LOG_PID | LOG_NDELAY, log_local);
}
return {};
}
static int syslog_translate(syslog_local_type log_local)
{
switch (log_local) {
case syslog_local_type::local0:
return LOG_LOCAL0;
case syslog_local_type::local1:
return LOG_LOCAL1;
case syslog_local_type::local2:
return LOG_LOCAL2;
case syslog_local_type::local3:
return LOG_LOCAL3;
case syslog_local_type::local4:
return LOG_LOCAL4;
case syslog_local_type::local5:
return LOG_LOCAL5;
case syslog_local_type::local6:
return LOG_LOCAL6;
case syslog_local_type::local7:
return LOG_LOCAL7;
default:
return LOG_LOCAL0;
break;
}
};
};
} // namespace srslog
#endif // SRSLOG_SYSLOG_SINK_H

View File

@ -13,6 +13,7 @@
#include "srsran/srslog/srslog.h"
#include "formatters/json_formatter.h"
#include "sinks/file_sink.h"
#include "sinks/syslog_sink.h"
#include "srslog_instance.h"
using namespace srslog;
@ -165,6 +166,25 @@ sink& srslog::fetch_file_sink(const std::string& path, size_t max_size, std::uni
return *s;
}
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;
}
bool srslog::install_custom_sink(const std::string& id, std::unique_ptr<sink> s)
{
assert(!id.empty() && "Empty path string");

View File

@ -35,6 +35,10 @@ target_include_directories(file_sink_test PUBLIC ../../)
target_link_libraries(file_sink_test srslog)
add_test(file_sink_test file_sink_test)
add_executable(syslog_sink_test syslog_sink_test.cpp)
target_include_directories(syslog_sink_test PUBLIC ../../)
target_link_libraries(syslog_sink_test srslog)
add_executable(file_utils_test file_utils_test.cpp)
target_include_directories(file_utils_test PUBLIC ../../)
target_link_libraries(file_utils_test srslog)

View File

@ -0,0 +1,63 @@
/**
*
* \section COPYRIGHT
*
* Copyright 2013-2021 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/sinks/syslog_sink.h"
#include "srsran/srslog/srslog.h"
#include "test_dummies.h"
#include "testing_helpers.h"
#include <fstream>
#include <sstream>
using namespace srslog;
/// Syslog sink name.
static constexpr char sink_name[] = "srslog_syslog_sink";
static bool find_string_infile(std::string filename, std::string pattern)
{
std::ifstream file(filename);
std::string line;
bool found = false;
if (file.is_open()) {
while (std::getline(file, line)) {
if (line.find(pattern) != std::string::npos) { // WILL SEARCH 2015-1113 in file
found = true;
}
}
} else {
printf("WARNING: Could not open file %s", filename.c_str());
}
return found;
}
static bool syslog_basic_test()
{
syslog_sink syslog_sink(get_default_log_formatter());
// Build a 1000 byte entry.
std::string entry(1000, 'a');
syslog_sink.write(detail::memory_buffer(entry));
syslog_sink.flush();
ASSERT_EQ(find_string_infile("/var/log/syslog", entry), true);
return true;
}
int main()
{
TEST_FUNCTION(syslog_basic_test);
return 0;
}