diff --git a/src/common/logging/common.cpp b/src/common/logging/common.cpp index 27cc904e..618dee02 100644 --- a/src/common/logging/common.cpp +++ b/src/common/logging/common.cpp @@ -41,8 +41,12 @@ constexpr char logging_verbosity_environment_variable[] = Logger::Logger(std::shared_ptr stream, Verbosity verbosity_level, - std::string prefix) - : verbosity(verbosity_level), stream(stream), prefix(prefix) {} + std::string prefix, + bool prefix_timestamp) + : verbosity(verbosity_level), + stream(stream), + prefix(prefix), + prefix_timestamp(prefix_timestamp) {} Logger Logger::create_from_environment(std::string prefix) { auto env = boost::this_process::environment(); @@ -92,22 +96,26 @@ Logger Logger::create_wine_stderr() { // we want the STDERR redirection from the group host processes to still // function here return Logger(std::shared_ptr(&std::cerr, [](auto*) {}), - verbosity_level, ""); + verbosity_level, "", false); } void Logger::log(const std::string& message) { - const auto current_time = std::chrono::system_clock::now(); - const std::time_t timestamp = - std::chrono::system_clock::to_time_t(current_time); - - // How did C++ manage to get time formatting libraries without a way to - // actually get a timestamp in a threadsafe way? `localtime_r` in C++ is not - // portable but luckily we only have to support GCC anyway. - std::tm tm; - localtime_r(×tamp, &tm); - std::ostringstream formatted_message; - formatted_message << std::put_time(&tm, "%T") << " "; + + if (prefix_timestamp) { + const auto current_time = std::chrono::system_clock::now(); + const std::time_t timestamp = + std::chrono::system_clock::to_time_t(current_time); + + // How did C++ manage to get time formatting libraries without a way to + // actually get a timestamp in a threadsafe way? `localtime_r` in C++ is + // not portable but luckily we only have to support GCC anyway. + std::tm tm; + localtime_r(×tamp, &tm); + + formatted_message << std::put_time(&tm, "%T") << " "; + } + formatted_message << prefix; formatted_message << message; // Flushing a stringstream doesn't do anything, but we need to put a diff --git a/src/common/logging/common.h b/src/common/logging/common.h index 608c43ab..4bcc0acd 100644 --- a/src/common/logging/common.h +++ b/src/common/logging/common.h @@ -95,11 +95,18 @@ class Logger { * `Logger::Verbosity` constants above for a description of the verbosity * levels. * @param prefix An optional prefix for the logger. Useful for differentiate - * messages coming from the Wine VST host. + * messages coming from the Wine VST host. Should end with a single space + * character. + * @param prefix_timestamp Whether the log messages should be prefixed with + * a timestamp. The timestamp is added before `prefix`. This is set to + * `false` in `create_wine_stderr()` because otherwise you would end up + * with a second timestamp in the middle of the message (since all Wine + * output gets relayed through the logger using `async_log_pipe_lines()`). */ Logger(std::shared_ptr stream, Verbosity verbosity_level, - std::string prefix = ""); + std::string prefix = "", + bool prefix_timestamp = false); /** * Create a logger instance based on the set environment variables. See the @@ -114,8 +121,6 @@ class Logger { * Create a special logger instance that outputs directly to STDERR without * any prefixes. This is used to be able to log filterable messages from the * Wine side of things. - * - * TODO: Don't prefix this with a timestamp */ static Logger create_wine_stderr(); @@ -179,8 +184,14 @@ class Logger { * or a file stream. */ std::shared_ptr stream; + /** * A prefix that gets prepended before every message. */ - std::string prefix; + const std::string prefix; + + /** + * Whether the log messages should be prefixed with a time stamp. + */ + const bool prefix_timestamp; };