mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Add a +editor flag to YABRIDGE_DEBUG_LEVEL
This commit is contained in:
@@ -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.
|
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
|
- Also added a warning for thisq in the initialization message if yabridge
|
||||||
detects a low value for `RLIMIT_MEMLOCK`.
|
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
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
`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
|
`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.
|
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
|
- `YABRIDGE_DEBUG_LEVEL={0,1,2}{,+editor}` allows you to set the verbosity of
|
||||||
information. Each level increases the amount of debug information printed:
|
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
|
- A value of `0` (the default) means that yabridge will only log the output
|
||||||
from the Wine process and some basic information about the
|
from the Wine process and some basic information about the
|
||||||
|
|||||||
@@ -41,21 +41,39 @@ constexpr char logging_file_environment_variable[] = "YABRIDGE_DEBUG_FILE";
|
|||||||
constexpr char logging_verbosity_environment_variable[] =
|
constexpr char logging_verbosity_environment_variable[] =
|
||||||
"YABRIDGE_DEBUG_LEVEL";
|
"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,
|
Logger::Logger(std::shared_ptr<std::ostream> stream,
|
||||||
Verbosity verbosity_level,
|
Verbosity verbosity_level,
|
||||||
|
bool editor_tracing,
|
||||||
std::string prefix,
|
std::string prefix,
|
||||||
bool prefix_timestamp)
|
bool prefix_timestamp)
|
||||||
: verbosity(verbosity_level),
|
: verbosity(verbosity_level),
|
||||||
|
editor_tracing(editor_tracing),
|
||||||
stream(stream),
|
stream(stream),
|
||||||
prefix(prefix),
|
prefix(prefix),
|
||||||
prefix_timestamp(prefix_timestamp) {}
|
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();
|
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 =
|
std::string verbosity =
|
||||||
env[logging_verbosity_environment_variable].to_string();
|
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
|
// Default to `Verbosity::basic` if the environment variable has not
|
||||||
// been set or if it is not an integer.
|
// been set or if it is not an integer.
|
||||||
Verbosity verbosity_level;
|
Verbosity verbosity_level;
|
||||||
@@ -65,41 +83,35 @@ Logger Logger::create_from_environment(std::string prefix) {
|
|||||||
verbosity_level = Verbosity::basic;
|
verbosity_level = Verbosity::basic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!stream) {
|
||||||
// If `file` points to a valid location then use create/truncate the
|
// If `file` points to a valid location then use create/truncate the
|
||||||
// file and write all of the logs there, otherwise use STDERR
|
// file and write all of the logs there, otherwise use STDERR
|
||||||
auto log_file = std::make_shared<std::ofstream>(
|
const auto log_file = std::make_shared<std::ofstream>(
|
||||||
file_path, std::fstream::out | std::fstream::app);
|
file_path, std::fstream::out | std::fstream::app);
|
||||||
if (log_file->is_open()) {
|
if (log_file->is_open()) {
|
||||||
return Logger(log_file, verbosity_level, prefix);
|
stream = log_file;
|
||||||
|
return Logger(log_file, verbosity_level, editor_tracing, prefix);
|
||||||
} else {
|
} else {
|
||||||
// For STDERR we sadly can't just use `std::cerr`. In the group process
|
// For STDERR we sadly can't just use `std::cerr`. In the group
|
||||||
// we need to capture all output generated by the process itself, and
|
// process we need to capture all output generated by the process
|
||||||
// the only way to do this is by reopening the STDERR and STDOUT streams
|
// itself, and the only way to do this is by reopening the STDERR
|
||||||
// to a pipe. Luckily `/dev/stderr` stays unaffected, so we can still
|
// and STDOUT streams to a pipe. Luckily `/dev/stderr` stays
|
||||||
// write there without causing infinite loops.
|
// unaffected, so we can still write there without causing infinite
|
||||||
return Logger(std::make_shared<std::ofstream>(
|
// loops.
|
||||||
"/dev/stderr", std::fstream::out | std::fstream::app),
|
stream = std::make_shared<std::ofstream>(
|
||||||
verbosity_level, prefix);
|
"/dev/stderr", std::fstream::out | std::fstream::app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Logger(stream, verbosity_level, editor_tracing, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
Logger Logger::create_wine_stderr() {
|
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're logging directly to `std::cerr` instead of to `/dev/stderr` because
|
||||||
// we want the STDERR redirection from the group host processes to still
|
// we want the STDERR redirection from the group host processes to still
|
||||||
// function here
|
// function here
|
||||||
return Logger(std::shared_ptr<std::ostream>(&std::cerr, [](auto*) {}),
|
return create_from_environment(
|
||||||
verbosity_level, "", false);
|
"", std::shared_ptr<std::ostream>(&std::cerr, [](auto*) {}));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::log(const std::string& message) {
|
void Logger::log(const std::string& message) {
|
||||||
|
|||||||
@@ -96,6 +96,9 @@ class Logger {
|
|||||||
* @param verbosity_level The verbosity of the logging, see the
|
* @param verbosity_level The verbosity of the logging, see the
|
||||||
* `Logger::Verbosity` constants above for a description of the verbosity
|
* `Logger::Verbosity` constants above for a description of the verbosity
|
||||||
* levels.
|
* 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
|
* @param prefix An optional prefix for the logger. Useful for differentiate
|
||||||
* messages coming from the Wine VST host. Should end with a single space
|
* messages coming from the Wine VST host. Should end with a single space
|
||||||
* character.
|
* character.
|
||||||
@@ -107,6 +110,7 @@ class Logger {
|
|||||||
*/
|
*/
|
||||||
Logger(std::shared_ptr<std::ostream> stream,
|
Logger(std::shared_ptr<std::ostream> stream,
|
||||||
Verbosity verbosity_level,
|
Verbosity verbosity_level,
|
||||||
|
bool editor_tracing,
|
||||||
std::string prefix = "",
|
std::string prefix = "",
|
||||||
bool prefix_timestamp = true);
|
bool prefix_timestamp = true);
|
||||||
|
|
||||||
@@ -116,8 +120,12 @@ class Logger {
|
|||||||
*
|
*
|
||||||
* @param prefix A message to prepend for every log message, useful to
|
* @param prefix A message to prepend for every log message, useful to
|
||||||
* differentiate between the Wine process and the Linux VST plugin.
|
* 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
|
* Create a special logger instance that outputs directly to STDERR without
|
||||||
@@ -173,7 +181,21 @@ class Logger {
|
|||||||
*/
|
*/
|
||||||
template <invocable_returning<std::string> F>
|
template <invocable_returning<std::string> F>
|
||||||
void log_trace(F&& fn) {
|
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());
|
log(fn());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,6 +206,12 @@ class Logger {
|
|||||||
*/
|
*/
|
||||||
const Verbosity verbosity;
|
const Verbosity verbosity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is set to true, then we'll print debug traces for the plugin
|
||||||
|
* editor.
|
||||||
|
*/
|
||||||
|
const bool editor_tracing;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* The output stream to write the log messages to. Typically either STDERR
|
* The output stream to write the log messages to. Typically either STDERR
|
||||||
|
|||||||
Reference in New Issue
Block a user