Sunshine0.0.5917
Sunshine 0.0.5917
Self-hosted game stream host for Moonlight.
Loading...
Searching...
No Matches
Go to the documentation of this file.
1
5#pragma once
6
7// standard includes
8#include <cstddef>
9#include <filesystem>
10#include <format>
11#include <string>
12#include <system_error>
13
14// lib includes
15#include <boost/log/common.hpp>
16#include <boost/log/sinks.hpp>
17
21using text_sink = boost::log::sinks::asynchronous_sink<boost::log::sinks::text_ostream_backend>;
22
23extern boost::log::sources::severity_logger<int> verbose;
24extern boost::log::sources::severity_logger<int> debug;
25extern boost::log::sources::severity_logger<int> info;
26extern boost::log::sources::severity_logger<int> warning;
27extern boost::log::sources::severity_logger<int> error;
28extern boost::log::sources::severity_logger<int> fatal;
29#ifdef SUNSHINE_TESTS
30extern boost::log::sources::severity_logger<int> tests;
31#endif
32
33#include "config.h"
34#include "stat_trackers.h"
35
39namespace logging {
43 inline constexpr std::size_t retained_log_file_count {5};
44
54 inline std::error_code rotate_log_file(const std::filesystem::path &log_file) noexcept {
55 const auto rotated_log_path = [&log_file](std::size_t generation) {
56 auto rotated_path = log_file;
57 rotated_path += std::format(".{}", generation);
58 return rotated_path;
59 };
60
61 try {
62 std::filesystem::remove(rotated_log_path(retained_log_file_count));
63
64 for (auto generation = retained_log_file_count; generation > 1; --generation) {
65 const auto previous_path = rotated_log_path(generation - 1);
66 if (std::filesystem::exists(previous_path)) {
67 std::filesystem::rename(previous_path, rotated_log_path(generation));
68 }
69 }
70
71 if (std::filesystem::exists(log_file)) {
72 std::filesystem::rename(log_file, rotated_log_path(1));
73 }
74
75 return {};
76 } catch (const std::filesystem::filesystem_error &filesystem_error) {
77 return filesystem_error.code();
78 }
79 }
80
84 class deinit_t {
85 public:
89 ~deinit_t();
90 };
91
98 void deinit();
99
106 void formatter(const boost::log::record_view &view, boost::log::formatting_ostream &os);
107
117 [[nodiscard]] std::unique_ptr<deinit_t> init(int min_log_level, const std::string &log_file);
118
123 void setup_av_logging(int min_log_level);
124
130 void setup_libdisplaydevice_logging(int min_log_level);
131
138 void log_flush();
139
147 void print_help(const char *name);
148
162 template<typename T>
164 public:
173 min_max_avg_periodic_logger(boost::log::sources::severity_logger<int> &severity, std::string_view message, std::string_view units, std::chrono::seconds interval_in_seconds = std::chrono::seconds(20)):
174 severity(severity),
175 message(message),
176 units(units),
177 interval(interval_in_seconds),
178 enabled(config::sunshine.min_log_level <= severity.default_severity()) {
179 }
180
186 void collect_and_log(const T &value) {
187 if (enabled) {
188 auto print_info = [this](const T &min_value, const T &max_value, double avg_value) {
190 if constexpr (std::is_floating_point_v<T>) {
191 BOOST_LOG(severity.get()) << message << " (min/max/avg): " << f % min_value << units << "/" << f % max_value << units << "/" << f % avg_value << units;
192 } else {
193 BOOST_LOG(severity.get()) << message << " (min/max/avg): " << min_value << units << "/" << max_value << units << "/" << f % avg_value << units;
194 }
195 };
196 tracker.collect_and_callback_on_interval(value, print_info, interval);
197 }
198 }
199
205 void collect_and_log(std::function<T()> func) {
206 if (enabled) {
207 collect_and_log(func());
208 }
209 }
210
214 void reset() {
215 if (enabled) {
216 tracker.reset();
217 }
218 }
219
225 bool is_enabled() const {
226 return enabled;
227 }
228
229 private:
230 std::reference_wrapper<boost::log::sources::severity_logger<int>> severity;
231 std::string message;
232 std::string units;
233 std::chrono::seconds interval;
234 bool enabled;
236 };
237
254 public:
262 time_delta_periodic_logger(boost::log::sources::severity_logger<int> &severity, std::string_view message, std::chrono::seconds interval_in_seconds = std::chrono::seconds(20)):
263 logger(severity, message, "ms", interval_in_seconds) {
264 }
265
271 void first_point(const std::chrono::steady_clock::time_point &point) {
272 if (logger.is_enabled()) {
273 point1 = point;
274 }
275 }
276
281 if (logger.is_enabled()) {
282 first_point(std::chrono::steady_clock::now());
283 }
284 }
285
291 void second_point_and_log(const std::chrono::steady_clock::time_point &point) {
292 if (logger.is_enabled()) {
293 logger.collect_and_log(std::chrono::duration<double, std::milli>(point - point1).count());
294 }
295 }
296
301 if (logger.is_enabled()) {
302 second_point_and_log(std::chrono::steady_clock::now());
303 }
304 }
305
309 void reset() {
310 if (logger.is_enabled()) {
311 logger.reset();
312 }
313 }
314
320 bool is_enabled() const {
321 return logger.is_enabled();
322 }
323
324 private:
325 std::chrono::steady_clock::time_point point1 = std::chrono::steady_clock::now();
327 };
328
334 std::string bracket(const std::string &input);
335
341 std::wstring bracket(const std::wstring &input);
342
343} // namespace logging
RAII helper that runs shutdown cleanup when destroyed.
Definition logging.h:84
A helper class for tracking and logging numerical values across a period of time.
Definition logging.h:163
void collect_and_log(std::function< T()> func)
Collect a metric sample and write it to the periodic log when due.
Definition logging.h:205
void collect_and_log(const T &value)
Collect a metric sample and report it with this logger's configured message and units when due.
Definition logging.h:186
bool is_enabled() const
Check whether this periodic logger should emit at the configured severity.
Definition logging.h:225
void reset()
Reset the object to its initial empty state.
Definition logging.h:214
min_max_avg_periodic_logger(boost::log::sources::severity_logger< int > &severity, std::string_view message, std::string_view units, std::chrono::seconds interval_in_seconds=std::chrono::seconds(20))
Construct a periodic logger that reports min, max, and average samples.
Definition logging.h:173
void reset()
Reset the object to its initial empty state.
Definition logging.h:309
bool is_enabled() const
Check whether this periodic logger should emit at the configured severity.
Definition logging.h:320
void second_point_now_and_log()
Store the current time as the second timestamp and log the elapsed interval.
Definition logging.h:300
void first_point_now()
Store the current time as the first timestamp.
Definition logging.h:280
void second_point_and_log(const std::chrono::steady_clock::time_point &point)
Store the second timestamp and log the elapsed interval.
Definition logging.h:291
void first_point(const std::chrono::steady_clock::time_point &point)
Store the first timestamp for a measured interval.
Definition logging.h:271
time_delta_periodic_logger(boost::log::sources::severity_logger< int > &severity, std::string_view message, std::chrono::seconds interval_in_seconds=std::chrono::seconds(20))
Construct a periodic logger for elapsed-time samples.
Definition logging.h:262
Accumulates minimum, maximum, and average values between periodic callbacks.
Definition stat_trackers.h:37
Declarations for the configuration of Sunshine.
bl::sources::severity_logger< int > debug
Follow what is happening.
Definition logging.cpp:43
bl::sources::severity_logger< int > error
Recoverable errors.
Definition logging.cpp:46
bl::sources::severity_logger< int > fatal
Unrecoverable errors.
Definition logging.cpp:47
bl::sources::severity_logger< int > info
Should be informed about.
Definition logging.cpp:44
bl::sources::severity_logger< int > verbose
Dominating output.
Definition logging.cpp:42
bl::sources::severity_logger< int > warning
Strange events.
Definition logging.cpp:45
boost::log::sinks::asynchronous_sink< boost::log::sinks::text_ostream_backend > text_sink
Boost.Log asynchronous text sink used by Sunshine logging.
Definition logging.h:21
Handles the initialization and deinitialization of the logging system.
Definition logging.cpp:54
void deinit()
Deinitialize the logging system.
Definition logging.cpp:59
constexpr std::size_t retained_log_file_count
The number of previous log files retained during rotation.
Definition logging.h:43
void setup_av_logging(int min_log_level)
Setup AV logging.
Definition logging.cpp:201
std::string bracket(const std::string &input)
Enclose string in square brackets.
Definition logging.cpp:286
void print_help(const char *name)
Print help to stdout.
Definition logging.cpp:266
std::unique_ptr< deinit_t > init(int min_log_level, const std::string &log_file)
Rotate the current log file and initialize the logging system.
Definition logging.cpp:155
void formatter(const boost::log::record_view &view, boost::log::formatting_ostream &os)
Format a Boost.Log record for Sunshine log output.
Definition logging.cpp:68
void setup_libdisplaydevice_logging(int min_log_level)
Set up libdisplaydevice logging, clamping to its supported enum values.
Definition logging.cpp:229
void log_flush()
Flush the log.
Definition logging.cpp:260
std::error_code rotate_log_file(const std::filesystem::path &log_file) noexcept
Rotate a log file while retaining up to five previous logs.
Definition logging.h:54
boost::format two_digits_after_decimal()
Create a Boost formatter with two fractional digits.
Definition stat_trackers.cpp:20
Declarations for streaming statistic tracking.