Add a +editor flag to YABRIDGE_DEBUG_LEVEL

This commit is contained in:
Robbert van der Helm
2021-07-20 02:48:12 +02:00
parent 9fcf91dc72
commit a1cb3b614b
4 changed files with 80 additions and 34 deletions
+4
View File
@@ -16,6 +16,10 @@ Versioning](https://semver.org/spec/v2.0.0.html).
shared memory for processing audio in plugins with a lot of inputs or outputs.
- Also added a warning for thisq in the initialization message if yabridge
detects a low value for `RLIMIT_MEMLOCK`.
- Added a `+editor` flag to the `YABRIDGE_DEBUG_LEVEL` environment variable that
can be combined with any debug level to also print debug tracing information
about the plugin editor window. This can be useful for diagnosing DAW or
window manager specific issues.
### Fixed
+4 -2
View File
@@ -784,8 +784,10 @@ offers these two environment variables to control yabridge's logging facilities:
`env YABRIDGE_DEBUG_FILE=/tmp/yabridge.log <daw>`, and then use
`tail -F /tmp/yabridge.log` to keep track of the output. If this option is not
present then yabridge will write all of its debug output to STDERR instead.
- `YABRIDGE_DEBUG_LEVEL={0,1,2}` allows you to set the verbosity of the debug
information. Each level increases the amount of debug information printed:
- `YABRIDGE_DEBUG_LEVEL={0,1,2}{,+editor}` allows you to set the verbosity of
the debug information. You can set a debug level, optionally followed by
`+editor` to also get more debug output related to the editor window handling.
Each level increases the amount of debug information printed:
- A value of `0` (the default) means that yabridge will only log the output
from the Wine process and some basic information about the
+42 -30
View File
@@ -41,21 +41,39 @@ constexpr char logging_file_environment_variable[] = "YABRIDGE_DEBUG_FILE";
constexpr char logging_verbosity_environment_variable[] =
"YABRIDGE_DEBUG_LEVEL";
/**
* The `YABRIDGE_DEBUG_LEVEL` flag for enabling editor tracing.
*/
constexpr char editor_tracing_flag[] = "+editor";
Logger::Logger(std::shared_ptr<std::ostream> stream,
Verbosity verbosity_level,
bool editor_tracing,
std::string prefix,
bool prefix_timestamp)
: verbosity(verbosity_level),
editor_tracing(editor_tracing),
stream(stream),
prefix(prefix),
prefix_timestamp(prefix_timestamp) {}
Logger Logger::create_from_environment(std::string prefix) {
Logger Logger::create_from_environment(std::string prefix,
std::shared_ptr<std::ostream> stream) {
bp::environment env = boost::this_process::environment();
std::string file_path = env[logging_file_environment_variable].to_string();
const std::string file_path =
env[logging_file_environment_variable].to_string();
std::string verbosity =
env[logging_verbosity_environment_variable].to_string();
// Editor debug tracing is an optional flag that can be added to any debug
// level (and technically it will also work fine if it's the only option,
// but you're not supposed to do that ;))
const bool editor_tracing = verbosity.ends_with(editor_tracing_flag);
if (editor_tracing) {
verbosity =
verbosity.substr(0, verbosity.size() - strlen(editor_tracing_flag));
}
// Default to `Verbosity::basic` if the environment variable has not
// been set or if it is not an integer.
Verbosity verbosity_level;
@@ -65,41 +83,35 @@ Logger Logger::create_from_environment(std::string prefix) {
verbosity_level = Verbosity::basic;
}
// If `file` points to a valid location then use create/truncate the
// file and write all of the logs there, otherwise use STDERR
auto log_file = std::make_shared<std::ofstream>(
file_path, std::fstream::out | std::fstream::app);
if (log_file->is_open()) {
return Logger(log_file, verbosity_level, prefix);
} else {
// For STDERR we sadly can't just use `std::cerr`. In the group process
// we need to capture all output generated by the process itself, and
// the only way to do this is by reopening the STDERR and STDOUT streams
// to a pipe. Luckily `/dev/stderr` stays unaffected, so we can still
// write there without causing infinite loops.
return Logger(std::make_shared<std::ofstream>(
"/dev/stderr", std::fstream::out | std::fstream::app),
verbosity_level, prefix);
if (!stream) {
// If `file` points to a valid location then use create/truncate the
// file and write all of the logs there, otherwise use STDERR
const auto log_file = std::make_shared<std::ofstream>(
file_path, std::fstream::out | std::fstream::app);
if (log_file->is_open()) {
stream = log_file;
return Logger(log_file, verbosity_level, editor_tracing, prefix);
} else {
// For STDERR we sadly can't just use `std::cerr`. In the group
// process we need to capture all output generated by the process
// itself, and the only way to do this is by reopening the STDERR
// and STDOUT streams to a pipe. Luckily `/dev/stderr` stays
// unaffected, so we can still write there without causing infinite
// loops.
stream = std::make_shared<std::ofstream>(
"/dev/stderr", std::fstream::out | std::fstream::app);
}
}
return Logger(stream, verbosity_level, editor_tracing, prefix);
}
Logger Logger::create_wine_stderr() {
bp::environment env = boost::this_process::environment();
std::string verbosity =
env[logging_verbosity_environment_variable].to_string();
Verbosity verbosity_level;
try {
verbosity_level = static_cast<Verbosity>(std::stoi(verbosity));
} catch (const std::invalid_argument&) {
verbosity_level = Verbosity::basic;
}
// We're logging directly to `std::cerr` instead of to `/dev/stderr` because
// we want the STDERR redirection from the group host processes to still
// function here
return Logger(std::shared_ptr<std::ostream>(&std::cerr, [](auto*) {}),
verbosity_level, "", false);
return create_from_environment(
"", std::shared_ptr<std::ostream>(&std::cerr, [](auto*) {}));
}
void Logger::log(const std::string& message) {
+30 -2
View File
@@ -96,6 +96,9 @@ class Logger {
* @param verbosity_level The verbosity of the logging, see the
* `Logger::Verbosity` constants above for a description of the verbosity
* levels.
* @param editor_tracing Whether we should enable debug tracing for the
* editor window handling. If we end up adding more of these options, we
* should move to a bitfield or something.
* @param prefix An optional prefix for the logger. Useful for differentiate
* messages coming from the Wine VST host. Should end with a single space
* character.
@@ -107,6 +110,7 @@ class Logger {
*/
Logger(std::shared_ptr<std::ostream> stream,
Verbosity verbosity_level,
bool editor_tracing,
std::string prefix = "",
bool prefix_timestamp = true);
@@ -116,8 +120,12 @@ class Logger {
*
* @param prefix A message to prepend for every log message, useful to
* differentiate between the Wine process and the Linux VST plugin.
* @param stream If specified, disregard `YABRIDGE_DEBUG_FILE` and output
* the log to this stream isntead.
*/
static Logger create_from_environment(std::string prefix = "");
static Logger create_from_environment(
std::string prefix = "",
std::shared_ptr<std::ostream> stream = nullptr);
/**
* Create a special logger instance that outputs directly to STDERR without
@@ -173,7 +181,21 @@ class Logger {
*/
template <invocable_returning<std::string> F>
void log_trace(F&& fn) {
if (verbosity >= Verbosity::all_events) {
if (verbosity >= Verbosity::all_events) [[unlikely]] {
log(fn());
}
}
/**
* Log a message that should only be printed when the `editor_tracing`
* option is enabled. This can be useful to provide debugging information
* for weird setup-specific bugs.
*
* @param message A lambda producing a string that should be written.
*/
template <invocable_returning<std::string> F>
void log_editor_trace(F&& fn) {
if (editor_tracing) [[unlikely]] {
log(fn());
}
}
@@ -184,6 +206,12 @@ class Logger {
*/
const Verbosity verbosity;
/**
* If this is set to true, then we'll print debug traces for the plugin
* editor.
*/
const bool editor_tracing;
private:
/**
* The output stream to write the log messages to. Typically either STDERR