make change_log_ignore a thing

This commit is contained in:
Christien Rioux 2024-03-07 12:38:20 -05:00
parent 6d7c62fb6b
commit 6455aff14a
12 changed files with 280 additions and 4 deletions

View File

@ -395,6 +395,27 @@ impl ClientApiConnection {
Ok(())
}
pub async fn server_change_log_ignore(
&self,
layer: String,
log_ignore: String,
) -> Result<(), String> {
trace!("ClientApiConnection::change_log_ignore");
let mut req = json::JsonValue::new_object();
req["op"] = "Control".into();
req["args"] = json::JsonValue::new_array();
req["args"].push("ChangeLogIgnore").unwrap();
req["args"].push(layer).unwrap();
req["args"].push(log_ignore).unwrap();
let Some(resp) = self.perform_request(req).await else {
return Err("Cancelled".to_owned());
};
if resp.has_key("error") {
return Err(resp["error"].to_string());
}
Ok(())
}
// Start Client API connection
pub async fn ipc_connect(&self, ipc_path: PathBuf) -> Result<(), String> {
trace!("ClientApiConnection::ipc_connect");

View File

@ -136,6 +136,9 @@ impl CommandProcessor {
all, terminal, system, api, file, otlp
levels include:
error, warn, info, debug, trace
change_log_ignore <layer> <changes> change the log target ignore list for a tracing layer
targets to add to the ignore list can be separated by a comma.
to remove a target from the ignore list, prepend it with a minus.
enable [flag] set a flag
disable [flag] unset a flag
valid flags in include:
@ -241,6 +244,41 @@ Server Debug Commands:
Ok(())
}
pub fn cmd_change_log_ignore(
&self,
rest: Option<String>,
callback: UICallback,
) -> Result<(), String> {
trace!("CommandProcessor::cmd_change_log_ignore");
let capi = self.capi();
let ui = self.ui_sender();
spawn_detached_local(async move {
let (layer, rest) = Self::word_split(&rest.unwrap_or_default());
let log_ignore = rest.unwrap_or_default();
match capi
.server_change_log_ignore(layer, log_ignore.clone())
.await
{
Ok(()) => {
ui.display_string_dialog(
"Log ignore changed",
&format!("Log ignore changed '{}'", log_ignore),
callback,
);
}
Err(e) => {
ui.display_string_dialog(
"Server command 'change_log_ignore' failed",
&e,
callback,
);
}
}
});
Ok(())
}
pub fn cmd_enable(&self, rest: Option<String>, callback: UICallback) -> Result<(), String> {
trace!("CommandProcessor::cmd_enable");
@ -295,6 +333,7 @@ Server Debug Commands:
"disconnect" => self.cmd_disconnect(callback),
"shutdown" => self.cmd_shutdown(callback),
"change_log_level" => self.cmd_change_log_level(rest, callback),
"change_log_ignore" => self.cmd_change_log_ignore(rest, callback),
"enable" => self.cmd_enable(rest, callback),
"disable" => self.cmd_disable(rest, callback),
_ => self.cmd_debug(command_line.to_owned(), callback),

View File

@ -1,5 +1,4 @@
use crate::*;
use std::path::PathBuf;
cfg_if::cfg_if! {
if #[cfg(not(target_arch = "wasm32"))] {
@ -310,6 +309,7 @@ pub fn get_default_ssl_directory(sub_path: &str) -> String {
if #[cfg(target_arch = "wasm32")] {
"".to_owned()
} else {
use std::path::PathBuf;
#[cfg(unix)]
{
let default_path = PathBuf::from("/etc/veilid-server/ssl").join(sub_path);
@ -555,6 +555,7 @@ fn get_default_store_path(store_type: &str) -> String {
if #[cfg(target_arch = "wasm32")] {
"".to_owned()
} else {
use std::path::PathBuf;
#[cfg(unix)]
{
let globalpath = PathBuf::from(format!("/var/db/veilid-server/{}", store_type));

View File

@ -125,6 +125,7 @@ abstract class Veilid {
void initializeVeilidCore(Map<String, dynamic> platformConfigJson);
void changeLogLevel(String layer, VeilidConfigLogLevel logLevel);
void changeLogIgnore(String layer, List<String> changes);
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config);
Future<VeilidState> getVeilidState();
Future<void> attach();

View File

@ -32,6 +32,8 @@ typedef _FreeStringDart = void Function(Pointer<Utf8>);
typedef _InitializeVeilidCoreDart = void Function(Pointer<Utf8>);
// fn change_log_level(layer: FfiStr, log_level: FfiStr)
typedef _ChangeLogLevelDart = void Function(Pointer<Utf8>, Pointer<Utf8>);
// fn change_log_ignore(layer: FfiStr, log_ignore: FfiStr)
typedef _ChangeLogIgnoreDart = void Function(Pointer<Utf8>, Pointer<Utf8>);
// fn startup_veilid_core(port: i64, config: FfiStr)
typedef _StartupVeilidCoreDart = void Function(int, int, Pointer<Utf8>);
// fn get_veilid_state(port: i64)
@ -1185,6 +1187,9 @@ class VeilidFFI extends Veilid {
_changeLogLevel = dylib.lookupFunction<
Void Function(Pointer<Utf8>, Pointer<Utf8>),
_ChangeLogLevelDart>('change_log_level'),
_changeLogIgnore = dylib.lookupFunction<
Void Function(Pointer<Utf8>, Pointer<Utf8>),
_ChangeLogIgnoreDart>('change_log_ignore'),
_startupVeilidCore = dylib.lookupFunction<
Void Function(Int64, Int64, Pointer<Utf8>),
_StartupVeilidCoreDart>('startup_veilid_core'),
@ -1408,6 +1413,7 @@ class VeilidFFI extends Veilid {
final _FreeStringDart _freeString;
final _InitializeVeilidCoreDart _initializeVeilidCore;
final _ChangeLogLevelDart _changeLogLevel;
final _ChangeLogIgnoreDart _changeLogIgnore;
final _StartupVeilidCoreDart _startupVeilidCore;
final _GetVeilidStateDart _getVeilidState;
final _AttachDart _attach;
@ -1508,6 +1514,16 @@ class VeilidFFI extends Veilid {
..free(nativeLogLevel);
}
@override
void changeLogIgnore(String layer, List<String> changes) {
final nativeChanges = jsonEncode(changes.join(',')).toNativeUtf8();
final nativeLayer = layer.toNativeUtf8();
_changeLogIgnore(nativeLayer, nativeChanges);
malloc
..free(nativeLayer)
..free(nativeChanges);
}
@override
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async {
final nativeConfig = jsonEncode(config).toNativeUtf8();

View File

@ -557,6 +557,13 @@ class VeilidJS extends Veilid {
wasm, 'change_log_level', [layer, logLevelJsonString]);
}
@override
void changeLogIgnore(String layer, List<String> changes) {
final changesJsonString = jsonEncode(changes.join(','));
js_util.callMethod<void>(
wasm, 'change_log_ignore', [layer, changesJsonString]);
}
@override
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async {
final streamController = StreamController<VeilidUpdate>();

View File

@ -321,6 +321,52 @@ pub extern "C" fn change_log_level(layer: FfiStr, log_level: FfiStr) {
}
}
fn apply_ignore_change(ignore_list: Vec<String>, target_change: String) -> Vec<String> {
let mut ignore_list = ignore_list.clone();
for change in target_change.split(',').map(|c| c.trim().to_owned()) {
if change.is_empty() {
continue;
}
if let Some(target) = change.strip_prefix('-') {
ignore_list.retain(|x| x != target);
} else if !ignore_list.contains(&change) {
ignore_list.push(change.to_string());
}
}
ignore_list
}
#[no_mangle]
pub extern "C" fn change_log_ignore(layer: FfiStr, log_ignore: FfiStr) {
// get layer to change level on
let layer = layer.into_opt_string().unwrap_or("all".to_owned());
let layer = if layer == "all" { "".to_owned() } else { layer };
// get changes to make
let log_ignore = log_ignore.into_opt_string().unwrap_or_default();
// change log level on appropriate layer
let filters = (*FILTERS).lock();
if layer.is_empty() {
// Change all layers
for f in filters.values() {
f.set_ignore_list(Some(apply_ignore_change(
f.ignore_list(),
log_ignore.clone(),
)));
}
} else {
// Change a specific layer
let f = filters.get(layer.as_str()).unwrap();
f.set_ignore_list(Some(apply_ignore_change(
f.ignore_list(),
log_ignore.clone(),
)));
}
}
#[no_mangle]
#[instrument]
pub extern "C" fn startup_veilid_core(port: i64, stream_port: i64, config: FfiStr) {

View File

@ -19,10 +19,10 @@ use wg::AsyncWaitGroup;
const MAX_NON_JSON_LOGGING: usize = 50;
cfg_if! {
if #[cfg(feature="rt-async-std")] {
use futures_util::{AsyncBufReadExt, AsyncWriteExt};
} else
} else
if #[cfg(feature="rt-tokio")] {
use tokio::io::AsyncBufReadExt;
use tokio::io::AsyncWriteExt;
@ -93,6 +93,13 @@ impl ClientApi {
veilid_logs.change_log_level(layer, log_level)
}
fn change_log_ignore(&self, layer: String, log_ignore: String) -> VeilidAPIResult<()> {
trace!("ClientApi::change_log_ignore");
let veilid_logs = self.inner.lock().veilid_logs.clone();
veilid_logs.change_log_ignore(layer, log_ignore)
}
#[instrument(level = "trace", skip(self))]
pub async fn stop(&self) {
trace!("ClientApi::stop requested");
@ -203,6 +210,12 @@ impl ClientApi {
let log_level = VeilidConfigLogLevel::from_str(&args[2])?;
self.change_log_level(args[1].clone(), log_level)?;
Ok("".to_owned())
} else if args[0] == "ChangeLogIgnore" {
if args.len() != 3 {
apibail_generic!("wrong number of arguments");
}
self.change_log_ignore(args[1].clone(), args[2].clone())?;
Ok("".to_owned())
} else if args[0] == "GetServerSettings" {
if args.len() != 1 {
apibail_generic!("wrong number of arguments");

View File

@ -229,4 +229,59 @@ impl VeilidLogs {
}
Ok(())
}
fn apply_ignore_change(ignore_list: Vec<String>, target_change: String) -> Vec<String> {
let mut ignore_list = ignore_list.clone();
for change in target_change.split(',').map(|c| c.trim().to_owned()) {
if change.is_empty() {
continue;
}
if let Some(target) = change.strip_prefix('-') {
ignore_list.retain(|x| x != target);
} else if !ignore_list.contains(&change) {
ignore_list.push(change.to_string());
}
}
ignore_list
}
pub fn change_log_ignore(
&self,
layer: String,
log_ignore: String,
) -> Result<(), veilid_core::VeilidAPIError> {
// get layer to change level on
let layer = if layer == "all" { "".to_owned() } else { layer };
// change log level on appropriate layer
let inner = self.inner.lock();
if layer.is_empty() {
// Change all layers
for f in inner.filters.values() {
f.set_ignore_list(Some(Self::apply_ignore_change(
f.ignore_list(),
log_ignore.clone(),
)));
}
} else {
// Change a specific layer
let f = match inner.filters.get(layer.as_str()) {
Some(f) => f,
None => {
return Err(veilid_core::VeilidAPIError::InvalidArgument {
context: "change_log_level".to_owned(),
argument: "layer".to_owned(),
value: layer,
});
}
};
f.set_ignore_list(Some(Self::apply_ignore_change(
f.ignore_list(),
log_ignore.clone(),
)));
}
Ok(())
}
}

View File

@ -260,6 +260,46 @@ pub fn change_log_level(layer: String, log_level: String) {
}
}
fn apply_ignore_change(ignore_list: Vec<String>, target_change: String) -> Vec<String> {
let mut ignore_list = ignore_list.clone();
for change in target_change.split(',').map(|c| c.trim().to_owned()) {
if change.is_empty() {
continue;
}
if let Some(target) = change.strip_prefix('-') {
ignore_list.retain(|x| x != target);
} else if !ignore_list.contains(&change) {
ignore_list.push(change.to_string());
}
}
ignore_list
}
#[wasm_bindgen()]
pub fn change_log_ignore(layer: String, log_ignore: String) {
let layer = if layer == "all" { "".to_owned() } else { layer };
let filters = (*FILTERS).borrow();
if layer.is_empty() {
// Change all layers
for f in filters.values() {
f.set_ignore_list(Some(apply_ignore_change(
f.ignore_list(),
log_ignore.clone(),
)));
}
} else {
// Change a specific layer
let f = filters.get(layer.as_str()).unwrap();
f.set_ignore_list(Some(apply_ignore_change(
f.ignore_list(),
log_ignore.clone(),
)));
}
}
#[wasm_bindgen()]
pub fn startup_veilid_core(update_callback_js: Function, json_config: String) -> Promise {
let update_callback_js = SendWrapper::new(update_callback_js);

View File

@ -129,6 +129,44 @@ impl VeilidClient {
}
}
fn apply_ignore_change(ignore_list: Vec<String>, changes: Vec<String>) -> Vec<String> {
let mut ignore_list = ignore_list.clone();
for change in changes.iter().map(|c| c.trim().to_owned()) {
if change.is_empty() {
continue;
}
if let Some(target) = change.strip_prefix('-') {
ignore_list.retain(|x| x != target);
} else if !ignore_list.contains(&change) {
ignore_list.push(change.to_string());
}
}
ignore_list
}
// TODO: can we refine the TS type of `layer`?
pub fn changeLogIgnore(layer: String, changes: Vec<String>) {
let layer = if layer == "all" { "".to_owned() } else { layer };
let filters = (*FILTERS).borrow();
if layer.is_empty() {
// Change all layers
for f in filters.values() {
f.set_ignore_list(Some(Self::apply_ignore_change(
f.ignore_list(),
changes.clone(),
)));
}
} else {
// Change a specific layer
let f = filters.get(layer.as_str()).unwrap();
f.set_ignore_list(Some(Self::apply_ignore_change(
f.ignore_list(),
changes.clone(),
)));
}
}
/// Shut down Veilid and terminate the API.
pub async fn shutdownCore() -> APIResult<()> {
let veilid_api = take_veilid_api()?;

View File

@ -2,7 +2,6 @@ use super::*;
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
pub use tsify::*;
pub use wasm_bindgen::prelude::*;
macro_rules! from_impl_to_jsvalue {