Make sure diagnostic log configuration file parse errors are logged

Parse  errors revert  to default  logging to  wsjtx_syslog.log with  a
suitable error message therein.
This commit is contained in:
Bill Somerville 2021-03-11 01:18:38 +00:00
parent c080a9ae40
commit 24b4e4a540
No known key found for this signature in database
GPG Key ID: D864B06D1E81618F
2 changed files with 84 additions and 67 deletions

View File

@ -142,8 +142,8 @@ namespace Logger
err += e.what ();
// Since we cannot be sure of boost log state, output to cerr and cout.
std::cerr << "ERROR: " << err << std::endl;
std::cout << "ERROR: " << err << std::endl;
LOG_ERROR (err);
throw;
}
}

View File

@ -104,59 +104,11 @@ namespace
<< context.category << ": " << msg.toStdWString ();
}
}
}
WSJTXLogging::WSJTXLogging ()
{
void default_log_config ()
{
auto core = logging::core::get ();
// Catch relevant exceptions from logging.
core->set_exception_handler
(
logging::make_exception_handler<std::runtime_error, std::logic_error> (exception_handler {})
);
// Check for a user-defined logging configuration settings file.
QFile log_config {QStandardPaths::locate (QStandardPaths::ConfigLocation, "wsjtx_log_config.ini")};
if (log_config.exists () && log_config.open (QFile::ReadOnly) && log_config.isReadable ())
{
QTextStream ts {&log_config};
auto config = ts.readAll ();
// Substitution variables.
container::flat_map<QString, QString> replacements =
{
{"DesktopLocation", QStandardPaths::writableLocation (QStandardPaths::DesktopLocation)},
{"DocumentsLocation", QStandardPaths::writableLocation (QStandardPaths::DocumentsLocation)},
{"TempLocation", QStandardPaths::writableLocation (QStandardPaths::TempLocation)},
{"HomeLocation", QStandardPaths::writableLocation (QStandardPaths::HomeLocation)},
{"CacheLocation", QStandardPaths::writableLocation (QStandardPaths::CacheLocation)},
{"GenericCacheLocation", QStandardPaths::writableLocation (QStandardPaths::GenericCacheLocation)},
{"GenericDataLocation", QStandardPaths::writableLocation (QStandardPaths::GenericDataLocation)},
{"AppDataLocation", QStandardPaths::writableLocation (QStandardPaths::AppDataLocation)},
{"AppLocalDataLocation", QStandardPaths::writableLocation (QStandardPaths::AppLocalDataLocation)},
};
// Parse the configration settings substituting the variable if found.
QString new_config;
int pos {0};
QRegularExpression subst_vars {R"(\${([^}]+)})"};
auto iter = subst_vars.globalMatch (config);
while (iter.hasNext ())
{
auto match = iter.next ();
auto const& name = match.captured (1);
auto repl_iter = replacements.find (name);
auto repl = repl_iter != replacements.end () ? repl_iter->second : "${" + name + "}";
new_config += config.mid (pos, match.capturedStart (1) - 2 - pos) + repl;
pos = match.capturedEnd (0);
}
new_config += config.mid (pos);
std::wstringbuf buffer {new_config.toStdWString (), std::ios_base::in};
std::wistream stream {&buffer};
Logger::init_from_config (stream);
LOG_INFO ("Read logging configuration file: " << log_config.fileName ());
}
else // Default setup
{
//
// Define sinks, filters, and formatters using expression
// templates for efficiency.
@ -219,10 +171,75 @@ WSJTXLogging::WSJTXLogging ()
);
core->add_sink (sys_sink);
}
// Indicate start of logging
LOG_INFO ("Log Start");
}
}
WSJTXLogging::WSJTXLogging ()
{
auto core = logging::core::get ();
// Catch relevant exceptions from logging.
core->set_exception_handler
(
logging::make_exception_handler<std::runtime_error, std::logic_error> (exception_handler {})
);
// Check for a user-defined logging configuration settings file.
QFile log_config {QStandardPaths::locate (QStandardPaths::ConfigLocation, "wsjtx_log_config.ini")};
if (log_config.exists () && log_config.open (QFile::ReadOnly) && log_config.isReadable ())
{
QTextStream ts {&log_config};
auto config = ts.readAll ();
// Substitution variables.
container::flat_map<QString, QString> replacements =
{
{"DesktopLocation", QStandardPaths::writableLocation (QStandardPaths::DesktopLocation)},
{"DocumentsLocation", QStandardPaths::writableLocation (QStandardPaths::DocumentsLocation)},
{"TempLocation", QStandardPaths::writableLocation (QStandardPaths::TempLocation)},
{"HomeLocation", QStandardPaths::writableLocation (QStandardPaths::HomeLocation)},
{"CacheLocation", QStandardPaths::writableLocation (QStandardPaths::CacheLocation)},
{"GenericCacheLocation", QStandardPaths::writableLocation (QStandardPaths::GenericCacheLocation)},
{"GenericDataLocation", QStandardPaths::writableLocation (QStandardPaths::GenericDataLocation)},
{"AppDataLocation", QStandardPaths::writableLocation (QStandardPaths::AppDataLocation)},
{"AppLocalDataLocation", QStandardPaths::writableLocation (QStandardPaths::AppLocalDataLocation)},
};
// Parse the configration settings substituting the variable if found.
QString new_config;
int pos {0};
QRegularExpression subst_vars {R"(\${([^}]+)})"};
auto iter = subst_vars.globalMatch (config);
while (iter.hasNext ())
{
auto match = iter.next ();
auto const& name = match.captured (1);
auto repl_iter = replacements.find (name);
auto repl = repl_iter != replacements.end () ? repl_iter->second : "${" + name + "}";
new_config += config.mid (pos, match.capturedStart (1) - 2 - pos) + repl;
pos = match.capturedEnd (0);
}
new_config += config.mid (pos);
std::wstringbuf buffer {new_config.toStdWString (), std::ios_base::in};
std::wistream stream {&buffer};
try
{
Logger::init_from_config (stream);
LOG_INFO ("Read logging configuration file: " << log_config.fileName ());
}
catch (std::exception const& e)
{
default_log_config ();
LOG_ERROR ("Reading logging configuration file: " << log_config.fileName () << " - " << e.what ());
LOG_INFO ("Reverting to default logging configuration");
}
}
else // Default setup
{
default_log_config ();
}
::qInstallMessageHandler (&qt_log_handler);
}