Add function for setting up file and windbg logs
And also writing panics to those logs.
This commit is contained in:
parent
a79099f573
commit
3b0291b4f5
60
Cargo.lock
generated
60
Cargo.lock
generated
|
@ -1813,6 +1813,15 @@ dependencies = [
|
||||||
"value-bag",
|
"value-bag",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log-panics"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae0136257df209261daa18d6c16394757c63e032e27aafd8b07788b051082bef"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru"
|
name = "lru"
|
||||||
version = "0.7.5"
|
version = "0.7.5"
|
||||||
|
@ -2005,14 +2014,18 @@ dependencies = [
|
||||||
"crossbeam",
|
"crossbeam",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
|
"log",
|
||||||
|
"log-panics",
|
||||||
"midi-consts",
|
"midi-consts",
|
||||||
"nih_plug_derive",
|
"nih_plug_derive",
|
||||||
"parking_lot 0.12.0",
|
"parking_lot 0.12.0",
|
||||||
"raw-window-handle",
|
"raw-window-handle",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"simplelog",
|
||||||
"vst3-sys",
|
"vst3-sys",
|
||||||
"widestring",
|
"widestring",
|
||||||
|
"win_dbg_logger",
|
||||||
"windows",
|
"windows",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2176,6 +2189,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objc"
|
name = "objc"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
@ -3019,6 +3041,17 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simplelog"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "48dfff04aade74dd495b007c831cd6f4e0cee19c344dd9dc0884c0289b70a786"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"termcolor",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sine"
|
name = "sine"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -3223,6 +3256,24 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
|
||||||
|
dependencies = [
|
||||||
|
"itoa 1.0.1",
|
||||||
|
"libc",
|
||||||
|
"num_threads",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-skia"
|
name = "tiny-skia"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
|
@ -3853,6 +3904,15 @@ version = "1.0.0-beta.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6f1efe828a707edf85994a4501734ac1c1b9d244cfcf4de235f11c4125ace8f"
|
checksum = "e6f1efe828a707edf85994a4501734ac1c1b9d244cfcf4de235f11c4125ace8f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "win_dbg_logger"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d1b4c22244dc27534d81e2f6fc3efd6b20e50c010f177efc20b719ec759a779"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
|
@ -60,11 +60,14 @@ cfg-if = "1.0"
|
||||||
clap-sys = { git = "https://github.com/robbert-vdh/clap-sys", branch = "update/clap-0.24" }
|
clap-sys = { git = "https://github.com/robbert-vdh/clap-sys", branch = "update/clap-0.24" }
|
||||||
crossbeam = "0.8"
|
crossbeam = "0.8"
|
||||||
lazy_static = "1.4"
|
lazy_static = "1.4"
|
||||||
|
log = { version = "0.4", features = ["std", "release_max_level_info"] }
|
||||||
|
log-panics = "2.0"
|
||||||
midi-consts = "0.1"
|
midi-consts = "0.1"
|
||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
raw-window-handle = "0.4"
|
raw-window-handle = "0.4"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
simplelog = "0.12"
|
||||||
vst3-sys = { git = "https://github.com/robbert-vdh/vst3-sys.git", branch = "fix/note-off-event", optional = true }
|
vst3-sys = { git = "https://github.com/robbert-vdh/vst3-sys.git", branch = "fix/note-off-event", optional = true }
|
||||||
widestring = "1.0.0-beta.1"
|
widestring = "1.0.0-beta.1"
|
||||||
|
|
||||||
|
@ -73,6 +76,11 @@ assert_no_alloc = { version = "1.1", optional = true }
|
||||||
[target.'cfg(all(target_family = "unix", not(target_os = "macos")))'.dependencies]
|
[target.'cfg(all(target_family = "unix", not(target_os = "macos")))'.dependencies]
|
||||||
libc = "0.2.124"
|
libc = "0.2.124"
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "windows")'.dependencies]
|
||||||
|
# STDIO isn't reliable on Windows, so when hosting plugins in a DAW it may be
|
||||||
|
# useful to log using `OutputDebugString()` instead
|
||||||
|
win_dbg_logger = "0.1"
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies.windows]
|
[target.'cfg(target_os = "windows")'.dependencies.windows]
|
||||||
version = "0.32"
|
version = "0.32"
|
||||||
features = [
|
features = [
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
|
use std::fs::File;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
/// The environment variable for controlling the logging behavior.
|
||||||
|
const NIH_LOG_ENV: &str = "NIH_LOG";
|
||||||
|
|
||||||
#[cfg(all(debug_assertions, feature = "assert_process_allocs"))]
|
#[cfg(all(debug_assertions, feature = "assert_process_allocs"))]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
|
@ -39,6 +44,83 @@ pub fn strlcpy(dest: &mut [c_char], src: &str) {
|
||||||
dest[copy_len] = 0;
|
dest[copy_len] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set up the logger so that the `nih_*!()` logging and assertion macros log output to a
|
||||||
|
/// centralized location and panics also get written there. By default this logs to STDERR unless
|
||||||
|
/// the user is running Windows and a debugger has been attached, in which case
|
||||||
|
/// `OutputDebugString()` will be used instead.
|
||||||
|
///
|
||||||
|
/// The logger's behavior can be controlled by setting the `NIH_LOG` environment variable to:
|
||||||
|
///
|
||||||
|
/// - `stderr`, in which case the log output always gets written to STDERR.
|
||||||
|
/// - `windbg` (only on Windows), in which case the output always gets logged using
|
||||||
|
/// `OutputDebugString()`.
|
||||||
|
/// - A file path, in which case the output gets appended to the end of that file which will be
|
||||||
|
/// created if necessary.
|
||||||
|
///
|
||||||
|
/// # TODO
|
||||||
|
///
|
||||||
|
/// Document `NIH_LOG` in an easier to find place.
|
||||||
|
pub fn setup_logger() {
|
||||||
|
// `win_dbg_logger` has no way to let us know that the logger has already been set up, so we'll
|
||||||
|
// need to do it this way
|
||||||
|
static LOGGER_SET_UP: AtomicBool = AtomicBool::new(false);
|
||||||
|
if LOGGER_SET_UP
|
||||||
|
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let nih_log_env = std::env::var(NIH_LOG_ENV);
|
||||||
|
let nih_log_env_str = nih_log_env.as_deref().unwrap_or("");
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
if nih_log_env_str.eq_ignore_ascii_case("windbg") || win_dbg_logger::is_debugger_present() {
|
||||||
|
win_dbg_logger::init();
|
||||||
|
log_panics::init();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If opening the file fails, then we'll log to STDERR anyways, hence this closure
|
||||||
|
let logger_config = simplelog::ConfigBuilder::new()
|
||||||
|
.set_thread_mode(simplelog::ThreadLogMode::Both)
|
||||||
|
.build();
|
||||||
|
let init_stderr_logger = || {
|
||||||
|
simplelog::TermLogger::init(
|
||||||
|
simplelog::LevelFilter::Trace,
|
||||||
|
logger_config.clone(),
|
||||||
|
simplelog::TerminalMode::Stderr,
|
||||||
|
simplelog::ColorChoice::Auto,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the logger has already been set up outside of this function then that won't cause any
|
||||||
|
// problems, so we can ignore the results here
|
||||||
|
if nih_log_env_str.eq_ignore_ascii_case("stderr") || nih_log_env_str.is_empty() {
|
||||||
|
let _ = init_stderr_logger();
|
||||||
|
} else {
|
||||||
|
let file = File::options()
|
||||||
|
.append(true)
|
||||||
|
.create(true)
|
||||||
|
.open(nih_log_env_str);
|
||||||
|
match file {
|
||||||
|
Ok(file) => {
|
||||||
|
let _ = simplelog::WriteLogger::init(
|
||||||
|
simplelog::LevelFilter::Trace,
|
||||||
|
logger_config,
|
||||||
|
file,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
let _ = init_stderr_logger();
|
||||||
|
nih_debug_assert_failure!("Could not open '{}': {:?}", nih_log_env_str, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_panics::init();
|
||||||
|
}
|
||||||
|
|
||||||
/// A wrapper around the entire process function, including the plugin wrapper parts. This sets up
|
/// A wrapper around the entire process function, including the plugin wrapper parts. This sets up
|
||||||
/// `assert_no_alloc` if needed, while also making sure that things like FTZ are set up correctly if
|
/// `assert_no_alloc` if needed, while also making sure that things like FTZ are set up correctly if
|
||||||
/// the host has not already done so.
|
/// the host has not already done so.
|
||||||
|
|
Loading…
Reference in a new issue