Option to disable message repeats suppressing

This commit is contained in:
Martin Pulec
2020-11-04 13:47:42 +01:00
parent c2ff176904
commit 024494f4b8
7 changed files with 101 additions and 22 deletions

View File

@@ -180,4 +180,68 @@ void debug_dump(void *lp, int len)
}
}
bool set_log_level(const char *optarg, bool *logger_repeat_msgs) {
using namespace std::string_literals;
using std::clog;
using std::cout;
*logger_repeat_msgs = false;
if (optarg == nullptr) {
log_level = LOG_LEVEL_VERBOSE;
return true;
}
static const struct { const char *name; int level; } mapping[] = {
{ "quiet", LOG_LEVEL_QUIET },
{ "fatal", LOG_LEVEL_FATAL },
{ "error", LOG_LEVEL_ERROR },
{ "warning", LOG_LEVEL_WARNING},
{ "notice", LOG_LEVEL_NOTICE},
{ "info", LOG_LEVEL_INFO },
{ "verbose", LOG_LEVEL_VERBOSE},
{ "debug", LOG_LEVEL_DEBUG },
{ "debug2", LOG_LEVEL_DEBUG2 },
};
if ("help"s == optarg) {
cout << "log level: [0-8";
for (auto m : mapping) {
cout << "|" << m.name;
}
cout << "][+repeat]\n";
cout << "\trepeat - print repeating log messages\n";
return false;
}
if (strstr(optarg, "+repeat") != nullptr) {
*logger_repeat_msgs = true;
}
if (optarg[0] == '+') {
return true;
}
if (isdigit(optarg[0])) {
long val = strtol(optarg, nullptr, 0);
if (val < 0 || val > LOG_LEVEL_MAX) {
clog << "Log: wrong value: " << log_level << "\n";
return false;
}
log_level = val;
return true;
}
for (auto m : mapping) {
if (strstr(optarg, m.name) == optarg) {
log_level = m.level;
return true;
}
}
LOG(LOG_LEVEL_ERROR) << "Wrong log level specification: " << optarg << "\n";
return false;
}
std::atomic<Logger::last_message *> Logger::last_msg{};
bool Logger::skip_repeated = true;

View File

@@ -40,6 +40,10 @@
#ifndef _RAT_DEBUG_H
#define _RAT_DEBUG_H
#ifndef __cplusplus
#include <stdbool.h>
#endif // ! defined __cplusplus
#define UNUSED(x) (x=x)
#define LOG_LEVEL_QUIET 0 ///< suppress all logging
@@ -74,6 +78,8 @@ void debug_dump(void*lp, int len);
#define debug_msg(...) log_msg(LOG_LEVEL_DEBUG, __VA_ARGS__)
void log_msg(int log_level, const char *format, ...) ATTRIBUTE(format (printf, 2, 3));
bool set_log_level(const char *optarg, bool *logger_repeat_msgs);
#ifdef __cplusplus
}
#endif
@@ -90,19 +96,19 @@ void log_msg(int log_level, const char *format, ...) ATTRIBUTE(format (printf, 2
class Logger
{
public:
static void preinit() {
if (!rang::rang_implementation::supportsColor()
|| !rang::rang_implementation::isTerminal(std::clog.rdbuf())) {
return;
}
// force ANSI sequences even when written to ostringstream
rang::setControlMode(rang::control::Force);
static void preinit(bool skip_repeated) {
Logger::skip_repeated = skip_repeated;
if (rang::rang_implementation::supportsColor()
&& rang::rang_implementation::isTerminal(std::clog.rdbuf())) {
// force ANSI sequences even when written to ostringstream
rang::setControlMode(rang::control::Force);
#ifdef _WIN32
// ANSI control sequences need to be explicitly set in Windows
if (rang::rang_implementation::setWinTermAnsiColors(std::clog.rdbuf())) {
rang::setWinTermMode(rang::winTerm::Ansi);
}
// ANSI control sequences need to be explicitly set in Windows
if (rang::rang_implementation::setWinTermAnsiColors(std::clog.rdbuf())) {
rang::setWinTermMode(rang::winTerm::Ansi);
}
#endif
}
}
inline Logger(int l) : level(l) {}
inline ~Logger() {
@@ -111,8 +117,7 @@ public:
std::string msg = oss.str();
// check for repeated message
if (rang::rang_implementation::isTerminal(std::clog.rdbuf())) {
if (skip_repeated && rang::rang_implementation::isTerminal(std::clog.rdbuf())) {
auto last = last_msg.exchange(nullptr);
if (last != nullptr && last->msg == msg) {
int count = last->count += 1;
@@ -150,6 +155,7 @@ private:
int level;
std::ostringstream oss;
static bool skip_repeated;
struct last_message {
std::string msg;
int count{0};

View File

@@ -696,7 +696,7 @@ int main(int argc, char **argv)
int i;
struct cmdline_parameters params;
if ((init = common_preinit(argc, argv)) == nullptr) {
if ((init = common_preinit(argc, argv, nullptr)) == nullptr) {
EXIT(EXIT_FAILURE);
}

View File

@@ -44,6 +44,8 @@
#include "config_win32.h"
#endif
#include <getopt.h>
#include "host.h"
#include "audio/audio_capture.h"
@@ -179,13 +181,20 @@ static int x11_error_handler(Display *d, XErrorEvent *e) {
}
#endif
struct init_data *common_preinit(int argc, char *argv[])
struct init_data *common_preinit(int argc, char *argv[], const char *log_opt)
{
struct init_data *init;
bool logger_repeat_msgs = false;
uv_argc = argc;
uv_argv = argv;
if (!set_log_level(log_opt, &logger_repeat_msgs)) {
return nullptr;
}
Logger::preinit(!logger_repeat_msgs);
#ifdef HAVE_X
void *handle = dlopen(X11_LIB_NAME, RTLD_NOW);
@@ -240,8 +249,6 @@ struct init_data *common_preinit(int argc, char *argv[])
perf_init();
perf_record(UVP_INIT, 0);
Logger::preinit();
return init;
}

View File

@@ -117,7 +117,7 @@ void set_audio_delay(int val);
#define RATE_FLAG_FIXED_RATE (1ll<<62ll) ///< use the bitrate as fixed, not capped
struct init_data;
struct init_data *common_preinit(int argc, char *argv[]);
struct init_data *common_preinit(int argc, char *argv[], const char *log_opt);
void common_cleanup(struct init_data *init_data);
/**

View File

@@ -739,6 +739,8 @@ int main(int argc, char *argv[])
const char *video_protocol = "ultragrid_rtp";
const char *video_protocol_opts = "";
const char *log_opt = nullptr;
// First we need to set verbosity level prior to everything else.
// common_preinit() uses the verbosity level.
while ((ch =
@@ -747,9 +749,9 @@ int main(int argc, char *argv[])
switch (ch) {
case OPT_VERBOSE:
if (optarg) {
log_level = atoi(optarg);
log_opt = optarg;
} else {
log_level = LOG_LEVEL_VERBOSE;
log_opt = "verbose";
}
break;
default:
@@ -758,7 +760,7 @@ int main(int argc, char *argv[])
}
optind = 1;
if ((init = common_preinit(argc, argv)) == nullptr) {
if ((init = common_preinit(argc, argv, log_opt)) == nullptr) {
log_msg(LOG_LEVEL_FATAL, "common_preinit() failed!\n");
EXIT(EXIT_FAILURE);
}

View File

@@ -144,7 +144,7 @@ static bool run_unit_tests()
int main(int argc, char **argv)
{
struct init_data *init = nullptr;
if ((init = common_preinit(argc, argv)) == nullptr) {
if ((init = common_preinit(argc, argv, nullptr)) == nullptr) {
return 2;
}