mirror of
https://github.com/velopack/velopack.git
synced 2025-10-25 15:19:22 +00:00
Add back logging callbacks to JS
This commit is contained in:
@@ -47,6 +47,10 @@ declare module "./load" {
|
||||
locator: string | null,
|
||||
autoApply: boolean,
|
||||
): void;
|
||||
|
||||
function js_set_logger_callback(
|
||||
cb: (loglevel: LogLevel, msg: string) => void,
|
||||
): void;
|
||||
}
|
||||
|
||||
type VelopackHookType =
|
||||
@@ -59,6 +63,8 @@ type VelopackHookType =
|
||||
|
||||
type VelopackHook = (version: string) => void;
|
||||
|
||||
type LogLevel = "info" | "warn" | "error" | "debug" | "trace";
|
||||
|
||||
/**
|
||||
* VelopackApp helps you to handle app activation events correctly.
|
||||
* This should be used as early as possible in your application startup code.
|
||||
@@ -153,6 +159,14 @@ export class VelopackApp {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a callback to receive log messages from VelopackApp.
|
||||
*/
|
||||
setLogger(callback: (loglevel: LogLevel, msg: string) => void): VelopackApp {
|
||||
addon.js_set_logger_callback(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to automatically apply downloaded updates on startup. This is ON by default.
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,7 @@ velopack.workspace = true
|
||||
serde_json.workspace = true
|
||||
semver.workspace = true
|
||||
log.workspace = true
|
||||
simplelog.workspace = true
|
||||
lazy_static.workspace = true
|
||||
neon.workspace = true
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ use std::thread;
|
||||
use velopack::sources::*;
|
||||
use velopack::*;
|
||||
|
||||
mod logger;
|
||||
|
||||
struct UpdateManagerWrapper {
|
||||
manager: UpdateManager,
|
||||
}
|
||||
@@ -275,12 +277,19 @@ fn js_appbuilder_run(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
||||
logging::default_logfile_path(LocationContext::FromCurrentExe)
|
||||
};
|
||||
|
||||
logging::init_logging("lib-nodejs", Some(&log_file), false, false);
|
||||
logging::init_logging("lib-nodejs", Some(&log_file), false, false, Some(logger::create_shared_logger()));
|
||||
builder.run();
|
||||
|
||||
Ok(undefined)
|
||||
}
|
||||
|
||||
fn js_set_logger_callback(mut cx: FunctionContext) -> JsResult<JsUndefined> {
|
||||
let arg_cb = cx.argument::<JsFunction>(0)?;
|
||||
let cb_root = arg_cb.root(&mut cx);
|
||||
logger::set_logger_callback(Some(cb_root), &mut cx);
|
||||
Ok(cx.undefined())
|
||||
}
|
||||
|
||||
#[neon::main]
|
||||
fn main(mut cx: ModuleContext) -> NeonResult<()> {
|
||||
cx.export_function("js_new_update_manager", js_new_update_manager)?;
|
||||
@@ -292,5 +301,6 @@ fn main(mut cx: ModuleContext) -> NeonResult<()> {
|
||||
cx.export_function("js_download_update_async", js_download_update_async)?;
|
||||
cx.export_function("js_wait_exit_then_apply_update", js_wait_exit_then_apply_update)?;
|
||||
cx.export_function("js_appbuilder_run", js_appbuilder_run)?;
|
||||
cx.export_function("js_set_logger_callback", js_set_logger_callback)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
83
src/lib-nodejs/velopack_nodeffi/src/logger.rs
Normal file
83
src/lib-nodejs/velopack_nodeffi/src/logger.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use log::{Level, LevelFilter, Log, Metadata, Record};
|
||||
use neon::{event::Channel, prelude::*};
|
||||
use simplelog::{Config, SharedLogger};
|
||||
|
||||
lazy_static! {
|
||||
static ref LOGGER_CB: Arc<Mutex<Option<Root<JsFunction>>>> = Arc::new(Mutex::new(None));
|
||||
static ref LOGGER_CHANNEL: Arc<Mutex<Option<Channel>>> = Arc::new(Mutex::new(None));
|
||||
}
|
||||
|
||||
struct LoggerImpl {}
|
||||
|
||||
impl SharedLogger for LoggerImpl {
|
||||
fn level(&self) -> LevelFilter {
|
||||
LevelFilter::max()
|
||||
}
|
||||
|
||||
fn config(&self) -> Option<&Config> {
|
||||
None
|
||||
}
|
||||
|
||||
fn as_log(self: Box<Self>) -> Box<dyn Log> {
|
||||
Box::new(*self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Log for LoggerImpl {
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
metadata.level() <= log::max_level()
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
if !self.enabled(record.metadata()) {
|
||||
return;
|
||||
}
|
||||
|
||||
let text = format!("{}", record.args());
|
||||
|
||||
let level = match record.level() {
|
||||
Level::Error => "error",
|
||||
Level::Warn => "warn",
|
||||
Level::Info => "info",
|
||||
Level::Debug => "debug",
|
||||
Level::Trace => "trace",
|
||||
};
|
||||
|
||||
if let Ok(channel_opt) = LOGGER_CHANNEL.lock() {
|
||||
if channel_opt.is_some() {
|
||||
let channel = channel_opt.as_ref().unwrap();
|
||||
|
||||
channel.send(move |mut cx| {
|
||||
if let Ok(cb_lock) = LOGGER_CB.lock() {
|
||||
if let Some(cb) = &*cb_lock {
|
||||
let undefined = cx.undefined();
|
||||
let args = vec![cx.string(level).upcast(), cx.string(text).upcast()];
|
||||
cb.to_inner(&mut cx).call(&mut cx, undefined, args)?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
}
|
||||
|
||||
pub fn create_shared_logger() -> Box<dyn SharedLogger> {
|
||||
Box::new(LoggerImpl {})
|
||||
}
|
||||
|
||||
pub fn set_logger_callback(callback: Option<Root<JsFunction>>, cx: &mut FunctionContext) {
|
||||
if let Ok(mut cb_lock) = LOGGER_CB.lock() {
|
||||
let cb_taken = cb_lock.take();
|
||||
if let Some(cb_exist) = cb_taken {
|
||||
cb_exist.drop(cx);
|
||||
}
|
||||
*cb_lock = callback;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user