Skip to content

Commit

Permalink
fix(logging): add logging namespace and create logging::init method
Browse files Browse the repository at this point in the history
  • Loading branch information
ReenigneArcher committed Apr 1, 2024
1 parent 6d1805b commit 0e083ed
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 152 deletions.
6 changes: 3 additions & 3 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1184,7 +1184,7 @@ namespace config {
auto line = argv[x];

if (line == "--help"sv) {
print_help(*argv);
logging::print_help(*argv);
return 1;
}
#ifdef _WIN32
Expand All @@ -1204,7 +1204,7 @@ namespace config {
break;
}
if (apply_flags(line + 1)) {
print_help(*argv);
logging::print_help(*argv);
return -1;
}
}
Expand All @@ -1218,7 +1218,7 @@ namespace config {
else {
TUPLE_EL(var, 1, parse_option(line, line_end));
if (!var) {
print_help(*argv);
logging::print_help(*argv);
return -1;
}

Expand Down
6 changes: 3 additions & 3 deletions src/entry_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ namespace args {
*
* EXAMPLES:
* ```cpp
* print_help("sunshine", 0, nullptr);
* help("sunshine", 0, nullptr);
* ```
*/
int
help(const char *name, int argc, char *argv[]) {
print_help(name);
logging::print_help(name);

Check warning on line 95 in src/entry_handler.cpp

View check run for this annotation

Codecov / codecov/patch

src/entry_handler.cpp#L95

Added line #L95 was not covered by tests
return 0;
}

Expand All @@ -109,7 +109,7 @@ namespace args {
*/
int
version(const char *name, int argc, char *argv[]) {
std::cout << PROJECT_NAME << " version: v" << PROJECT_VER << std::endl;
// version was already logged at startup
return 0;
}

Expand Down
210 changes: 169 additions & 41 deletions src/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

// standard includes
#include <fstream>
#include <iostream>

// lib includes
Expand All @@ -16,6 +17,10 @@
// local includes
#include "logging.h"

extern "C" {
#include <libavutil/log.h>
}

using namespace std::literals;

namespace bl = boost::log;
Expand All @@ -29,45 +34,168 @@ bl::sources::severity_logger<int> warning(3); // Strange events
bl::sources::severity_logger<int> error(4); // Recoverable errors
bl::sources::severity_logger<int> fatal(5); // Unrecoverable errors

/**
* @brief Flush the log.
*
* EXAMPLES:
* ```cpp
* log_flush();
* ```
*/
void
log_flush() {
sink->flush();
}
struct NoDelete {
void
operator()(void *) {}
};

/**
* @brief Print help to stdout.
* @param name The name of the program.
*
* EXAMPLES:
* ```cpp
* print_help("sunshine");
* ```
*/
void
print_help(const char *name) {
std::cout
<< "Usage: "sv << name << " [options] [/path/to/configuration_file] [--cmd]"sv << std::endl
<< " Any configurable option can be overwritten with: \"name=value\""sv << std::endl
<< std::endl
<< " Note: The configuration will be created if it doesn't exist."sv << std::endl
<< std::endl
<< " --help | print help"sv << std::endl
<< " --creds username password | set user credentials for the Web manager"sv << std::endl
<< " --version | print the version of sunshine"sv << std::endl
<< std::endl
<< " flags"sv << std::endl
<< " -0 | Read PIN from stdin"sv << std::endl
<< " -1 | Do not load previously saved state and do retain any state after shutdown"sv << std::endl
<< " | Effectively starting as if for the first time without overwriting any pairings with your devices"sv << std::endl
<< " -2 | Force replacement of headers in video stream"sv << std::endl
<< " -p | Enable/Disable UPnP"sv << std::endl
<< std::endl;
}
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)

namespace logging {
/**
* @brief A destructor that restores the initial state.
*/
deinit_t::~deinit_t() {
deinit();
}

/**
* @brief Deinitialize the logging system.
*
* EXAMPLES:
* ```cpp
* deinit();
* ```
*/
void
deinit() {
bl::core::get()->remove_sink(sink);
sink.reset();
}

/**
* @brief Initialize the logging system.
* @param min_log_level The minimum log level to output.
* @param log_file The log file to write to.
* @returns A deinit_t object that will deinitialize the logging system when it goes out of scope.
*
* EXAMPLES:
* ```cpp
* log_init(2, "sunshine.log");
* ```
*/
std::unique_ptr<deinit_t>
init(int min_log_level, const std::string &log_file) {
if (min_log_level >= 1) {
av_log_set_level(AV_LOG_QUIET);
}
else {
av_log_set_level(AV_LOG_DEBUG);

Check warning on line 83 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L83

Added line #L83 was not covered by tests
}
av_log_set_callback([](void *ptr, int level, const char *fmt, va_list vl) {
static int print_prefix = 1;

Check warning on line 86 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L86

Added line #L86 was not covered by tests
char buffer[1024];

av_log_format_line(ptr, level, fmt, vl, buffer, sizeof(buffer), &print_prefix);
if (level <= AV_LOG_ERROR) {
// We print AV_LOG_FATAL at the error level. FFmpeg prints things as fatal that
// are expected in some cases, such as lack of codec support or similar things.
BOOST_LOG(error) << buffer;
}
else if (level <= AV_LOG_WARNING) {
BOOST_LOG(warning) << buffer;
}
else if (level <= AV_LOG_INFO) {
BOOST_LOG(info) << buffer;
}
else if (level <= AV_LOG_VERBOSE) {
// AV_LOG_VERBOSE is less verbose than AV_LOG_DEBUG
BOOST_LOG(debug) << buffer;
}

Check warning on line 104 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L104

Added line #L104 was not covered by tests
else {
BOOST_LOG(verbose) << buffer;
}
});

sink = boost::make_shared<text_sink>();

boost::shared_ptr<std::ostream> stream { &std::cout, NoDelete {} };
sink->locked_backend()->add_stream(stream);
sink->locked_backend()->add_stream(boost::make_shared<std::ofstream>(log_file));
sink->set_filter(severity >= min_log_level);

sink->set_formatter([message = "Message"s, severity = "Severity"s](const bl::record_view &view, bl::formatting_ostream &os) {
constexpr int DATE_BUFFER_SIZE = 21 + 2 + 1; // Full string plus ": \0"

Check warning on line 118 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L118

Added line #L118 was not covered by tests

auto log_level = view.attribute_values()[severity].extract<int>().get();

std::string_view log_type;

Check warning on line 122 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L122

Added line #L122 was not covered by tests
switch (log_level) {
case 0:
log_type = "Verbose: "sv;
break;
case 1:
log_type = "Debug: "sv;
break;
case 2:
log_type = "Info: "sv;
break;
case 3:
log_type = "Warning: "sv;
break;
case 4:
log_type = "Error: "sv;
break;
case 5:
log_type = "Fatal: "sv;
break;
};

Check warning on line 142 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L124-L142

Added lines #L124 - L142 were not covered by tests

char _date[DATE_BUFFER_SIZE];
std::time_t t = std::time(nullptr);
strftime(_date, DATE_BUFFER_SIZE, "[%Y:%m:%d:%H:%M:%S]: ", std::localtime(&t));

Check warning on line 146 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L144-L146

Added lines #L144 - L146 were not covered by tests

os << _date << log_type << view.attribute_values()[message].extract<std::string>();
});

Check warning on line 149 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L149

Added line #L149 was not covered by tests

// Flush after each log record to ensure log file contents on disk isn't stale.
// This is particularly important when running from a Windows service.
sink->locked_backend()->auto_flush(true);

bl::core::get()->add_sink(sink);
return std::make_unique<deinit_t>();
}

/**
* @brief Flush the log.
*
* EXAMPLES:
* ```cpp
* log_flush();
* ```
*/
void
log_flush() {
sink->flush();
}

Check warning on line 170 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L168-L170

Added lines #L168 - L170 were not covered by tests

/**
* @brief Print help to stdout.
* @param name The name of the program.
*
* EXAMPLES:
* ```cpp
* print_help("sunshine");
* ```
*/
void
print_help(const char *name) {
std::cout
<< "Usage: "sv << name << " [options] [/path/to/configuration_file] [--cmd]"sv << std::endl
<< " Any configurable option can be overwritten with: \"name=value\""sv << std::endl
<< std::endl
<< " Note: The configuration will be created if it doesn't exist."sv << std::endl
<< std::endl
<< " --help | print help"sv << std::endl
<< " --creds username password | set user credentials for the Web manager"sv << std::endl
<< " --version | print the version of sunshine"sv << std::endl
<< std::endl
<< " flags"sv << std::endl
<< " -0 | Read PIN from stdin"sv << std::endl
<< " -1 | Do not load previously saved state and do retain any state after shutdown"sv << std::endl
<< " | Effectively starting as if for the first time without overwriting any pairings with your devices"sv << std::endl
<< " -2 | Force replacement of headers in video stream"sv << std::endl
<< " -p | Enable/Disable UPnP"sv << std::endl
<< std::endl;
}

Check warning on line 200 in src/logging.cpp

View check run for this annotation

Codecov / codecov/patch

src/logging.cpp#L182-L200

Added lines #L182 - L200 were not covered by tests
} // namespace logging
23 changes: 18 additions & 5 deletions src/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
#include <boost/log/common.hpp>
#include <boost/log/sinks.hpp>

// local includes
#include <src/utility.h>

extern boost::shared_ptr<boost::log::sinks::asynchronous_sink<boost::log::sinks::text_ostream_backend>> sink;
using text_sink = boost::log::sinks::asynchronous_sink<boost::log::sinks::text_ostream_backend>;

Expand All @@ -20,8 +23,18 @@ extern boost::log::sources::severity_logger<int> warning;
extern boost::log::sources::severity_logger<int> error;
extern boost::log::sources::severity_logger<int> fatal;

// functions
void
log_flush();
void
print_help(const char *name);
namespace logging {
class deinit_t {
public:
~deinit_t();
};

void
deinit();
std::unique_ptr<deinit_t>
init(int min_log_level, const std::string &log_file);
void
log_flush();
void
print_help(const char *name);
} // namespace logging
Loading

0 comments on commit 0e083ed

Please sign in to comment.