forked from 1b-agent/opencadstudio-upstream
feat(plugin): quiet plugin IPC logs; print one "Loaded plugin" line
A normal run dumped the whole host↔runner trace (spawn, handshake, every per-command dispatch and request/response) to the terminal. Gate that behind OCS_PLUGIN_VERBOSE and, in normal runs, print just one line per plugin: `Loaded plugin: <name> (<id> <version>)`. The chatty host-side `[plugin]` lines now go through a `vlog!` macro that only fires when OCS_PLUGIN_VERBOSE is set. Runner-side logs were already suppressed (the runner is spawned with stderr = null); the remaining `[plugin]` lines in the IPC client are genuine error messages, left as-is. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
2723e4d47f
commit
e3d1780a69
1 file changed
+33
-8
@@ -24,6 +24,25 @@ use serde::de::DeserializeOwned;
|
|||||||
mod manager;
|
mod manager;
|
||||||
pub use manager::{DispatchResult, PluginManager};
|
pub use manager::{DispatchResult, PluginManager};
|
||||||
|
|
||||||
|
/// Whether verbose plugin-IPC logging is on. Off by default so a normal run
|
||||||
|
/// only prints the one-line "Loaded plugin" notice; set `OCS_PLUGIN_VERBOSE=1`
|
||||||
|
/// (any value) to see the spawn / handshake / per-dispatch request-response
|
||||||
|
/// trace.
|
||||||
|
pub(crate) fn verbose() -> bool {
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
static V: OnceLock<bool> = OnceLock::new();
|
||||||
|
*V.get_or_init(|| std::env::var_os("OCS_PLUGIN_VERBOSE").is_some())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `eprintln!` that only fires in verbose mode (see [`verbose`]).
|
||||||
|
macro_rules! vlog {
|
||||||
|
($($arg:tt)*) => {{
|
||||||
|
if crate::process::verbose() {
|
||||||
|
eprintln!($($arg)*);
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
/// Maximum time to wait for the plugin runner to connect back to the host.
|
/// Maximum time to wait for the plugin runner to connect back to the host.
|
||||||
const SPAWN_TIMEOUT: Duration = Duration::from_secs(10);
|
const SPAWN_TIMEOUT: Duration = Duration::from_secs(10);
|
||||||
|
|
||||||
@@ -126,7 +145,7 @@ impl PluginProcess {
|
|||||||
.to_ns_name::<GenericNamespaced>()
|
.to_ns_name::<GenericNamespaced>()
|
||||||
.expect("valid namespaced name");
|
.expect("valid namespaced name");
|
||||||
let runner_path = runner_executable()?;
|
let runner_path = runner_executable()?;
|
||||||
eprintln!(
|
vlog!(
|
||||||
"[plugin] spawning runner {} for {}",
|
"[plugin] spawning runner {} for {}",
|
||||||
runner_path.display(),
|
runner_path.display(),
|
||||||
cdylib_path.display()
|
cdylib_path.display()
|
||||||
@@ -156,7 +175,7 @@ impl PluginProcess {
|
|||||||
});
|
});
|
||||||
let stream = match rx.recv_timeout(spawn_timeout()) {
|
let stream = match rx.recv_timeout(spawn_timeout()) {
|
||||||
Ok(Ok(stream)) => {
|
Ok(Ok(stream)) => {
|
||||||
eprintln!("[plugin] runner connected");
|
vlog!("[plugin] runner connected");
|
||||||
Mutex::new(Some(stream))
|
Mutex::new(Some(stream))
|
||||||
}
|
}
|
||||||
Ok(Err(e)) => return Err(e.into()),
|
Ok(Err(e)) => return Err(e.into()),
|
||||||
@@ -200,6 +219,12 @@ impl PluginProcess {
|
|||||||
HostResponse::Manifest(m) => m,
|
HostResponse::Manifest(m) => m,
|
||||||
other => return Err(PluginError::UnexpectedResponse(other)),
|
other => return Err(PluginError::UnexpectedResponse(other)),
|
||||||
};
|
};
|
||||||
|
// Normal-run notice: just the loaded plugin's name (id + version). The
|
||||||
|
// full IPC trace above/below is gated behind OCS_PLUGIN_VERBOSE.
|
||||||
|
eprintln!(
|
||||||
|
"Loaded plugin: {} ({} {})",
|
||||||
|
manifest.name, manifest.id, manifest.version
|
||||||
|
);
|
||||||
let ribbon = match call(&stream, &child, host, HostRequest::GetRibbon, no_op)? {
|
let ribbon = match call(&stream, &child, host, HostRequest::GetRibbon, no_op)? {
|
||||||
HostResponse::Ribbon(r) => r,
|
HostResponse::Ribbon(r) => r,
|
||||||
other => return Err(PluginError::UnexpectedResponse(other)),
|
other => return Err(PluginError::UnexpectedResponse(other)),
|
||||||
@@ -233,7 +258,7 @@ impl PluginProcess {
|
|||||||
cmd: &str,
|
cmd: &str,
|
||||||
on_start_interactive: &mut dyn FnMut(u64),
|
on_start_interactive: &mut dyn FnMut(u64),
|
||||||
) -> Result<bool, PluginError> {
|
) -> Result<bool, PluginError> {
|
||||||
eprintln!("[plugin] dispatching {cmd}");
|
vlog!("[plugin] dispatching {cmd}");
|
||||||
let result = match call(
|
let result = match call(
|
||||||
&self.stream,
|
&self.stream,
|
||||||
&self.child,
|
&self.child,
|
||||||
@@ -246,7 +271,7 @@ impl PluginProcess {
|
|||||||
HostResponse::Bool(b) => Ok(b),
|
HostResponse::Bool(b) => Ok(b),
|
||||||
other => Err(PluginError::UnexpectedResponse(other)),
|
other => Err(PluginError::UnexpectedResponse(other)),
|
||||||
};
|
};
|
||||||
eprintln!("[plugin] dispatch {cmd} result: {result:?}");
|
vlog!("[plugin] dispatch {cmd} result: {result:?}");
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,7 +517,7 @@ fn call(
|
|||||||
let kind = request_kind(&req);
|
let kind = request_kind(&req);
|
||||||
let timeout = request_timeout(kind);
|
let timeout = request_timeout(kind);
|
||||||
let deadline = Instant::now() + timeout;
|
let deadline = Instant::now() + timeout;
|
||||||
eprintln!("[plugin] host -> runner: {req:?}");
|
vlog!("[plugin] host -> runner: {req:?}");
|
||||||
{
|
{
|
||||||
let mut guard = stream.lock().unwrap_or_else(|e| e.into_inner());
|
let mut guard = stream.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
let stream = guard.as_mut().ok_or_else(shutdown_error)?;
|
let stream = guard.as_mut().ok_or_else(shutdown_error)?;
|
||||||
@@ -500,12 +525,12 @@ fn call(
|
|||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
let msg = recv_with_deadline::<PluginToHost>(stream, child, deadline, timeout, kind)?;
|
let msg = recv_with_deadline::<PluginToHost>(stream, child, deadline, timeout, kind)?;
|
||||||
eprintln!("[plugin] runner -> host: {msg:?}");
|
vlog!("[plugin] runner -> host: {msg:?}");
|
||||||
match msg {
|
match msg {
|
||||||
PluginToHost::Response(resp) => return Ok(resp),
|
PluginToHost::Response(resp) => return Ok(resp),
|
||||||
PluginToHost::Request(plugin_req) => {
|
PluginToHost::Request(plugin_req) => {
|
||||||
let resp = handle_plugin_request(host, plugin_req, on_start_interactive);
|
let resp = handle_plugin_request(host, plugin_req, on_start_interactive);
|
||||||
eprintln!("[plugin] host -> runner response: {resp:?}");
|
vlog!("[plugin] host -> runner response: {resp:?}");
|
||||||
let mut guard = stream.lock().unwrap_or_else(|e| e.into_inner());
|
let mut guard = stream.lock().unwrap_or_else(|e| e.into_inner());
|
||||||
let stream = guard.as_mut().ok_or_else(shutdown_error)?;
|
let stream = guard.as_mut().ok_or_else(shutdown_error)?;
|
||||||
send(stream, &HostToPlugin::Response(resp))?;
|
send(stream, &HostToPlugin::Response(resp))?;
|
||||||
@@ -592,7 +617,7 @@ fn verify_runner_handshake(
|
|||||||
) -> Result<(), PluginError> {
|
) -> Result<(), PluginError> {
|
||||||
match handshake {
|
match handshake {
|
||||||
RunnerHandshake::Token(ref presented) if presented == expected_token => {
|
RunnerHandshake::Token(ref presented) if presented == expected_token => {
|
||||||
eprintln!("[plugin] runner authenticated");
|
vlog!("[plugin] runner authenticated");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
RunnerHandshake::Token(_) => Err(PluginError::Runner("authentication failed".into())),
|
RunnerHandshake::Token(_) => Err(PluginError::Runner("authentication failed".into())),
|
||||||
|
|||||||
Reference in new issue
Block a user