mirror of
https://github.com/bitwarden/browser
synced 2025-12-13 14:53:33 +00:00
Support for logging from NAPI (#14335)
* Support for log to electron console from NAPI * Fix test mock
This commit is contained in:
1
apps/desktop/desktop_native/Cargo.lock
generated
1
apps/desktop/desktop_native/Cargo.lock
generated
@@ -987,6 +987,7 @@ dependencies = [
|
|||||||
"base64",
|
"base64",
|
||||||
"desktop_core",
|
"desktop_core",
|
||||||
"hex",
|
"hex",
|
||||||
|
"log",
|
||||||
"napi",
|
"napi",
|
||||||
"napi-build",
|
"napi-build",
|
||||||
"napi-derive",
|
"napi-derive",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ base64 = { workspace = true }
|
|||||||
hex = { workspace = true }
|
hex = { workspace = true }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
desktop_core = { path = "../core" }
|
desktop_core = { path = "../core" }
|
||||||
|
log = { workspace = true }
|
||||||
napi = { workspace = true, features = ["async"] }
|
napi = { workspace = true, features = ["async"] }
|
||||||
napi-derive = { workspace = true }
|
napi-derive = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
|||||||
10
apps/desktop/desktop_native/napi/index.d.ts
vendored
10
apps/desktop/desktop_native/napi/index.d.ts
vendored
@@ -185,3 +185,13 @@ export declare namespace crypto {
|
|||||||
export declare namespace passkey_authenticator {
|
export declare namespace passkey_authenticator {
|
||||||
export function register(): void
|
export function register(): void
|
||||||
}
|
}
|
||||||
|
export declare namespace logging {
|
||||||
|
export const enum LogLevel {
|
||||||
|
Trace = 0,
|
||||||
|
Debug = 1,
|
||||||
|
Info = 2,
|
||||||
|
Warn = 3,
|
||||||
|
Error = 4
|
||||||
|
}
|
||||||
|
export function initNapiLog(jsLogFn: (err: Error | null, arg0: LogLevel, arg1: string) => any): void
|
||||||
|
}
|
||||||
|
|||||||
@@ -807,3 +807,61 @@ pub mod passkey_authenticator {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub mod logging {
|
||||||
|
use log::{Level, Metadata, Record};
|
||||||
|
use napi::threadsafe_function::{
|
||||||
|
ErrorStrategy::CalleeHandled, ThreadsafeFunction, ThreadsafeFunctionCallMode,
|
||||||
|
};
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
struct JsLogger(OnceLock<ThreadsafeFunction<(LogLevel, String), CalleeHandled>>);
|
||||||
|
static JS_LOGGER: JsLogger = JsLogger(OnceLock::new());
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub enum LogLevel {
|
||||||
|
Trace,
|
||||||
|
Debug,
|
||||||
|
Info,
|
||||||
|
Warn,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Level> for LogLevel {
|
||||||
|
fn from(level: Level) -> Self {
|
||||||
|
match level {
|
||||||
|
Level::Trace => LogLevel::Trace,
|
||||||
|
Level::Debug => LogLevel::Debug,
|
||||||
|
Level::Info => LogLevel::Info,
|
||||||
|
Level::Warn => LogLevel::Warn,
|
||||||
|
Level::Error => LogLevel::Error,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[napi]
|
||||||
|
pub fn init_napi_log(js_log_fn: ThreadsafeFunction<(LogLevel, String), CalleeHandled>) {
|
||||||
|
let _ = JS_LOGGER.0.set(js_log_fn);
|
||||||
|
let _ = log::set_logger(&JS_LOGGER);
|
||||||
|
log::set_max_level(log::LevelFilter::Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl log::Log for JsLogger {
|
||||||
|
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||||
|
metadata.level() <= log::max_level()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log(&self, record: &Record) {
|
||||||
|
if !self.enabled(record.metadata()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let Some(logger) = self.0.get() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let msg = (record.level().into(), record.args().to_string());
|
||||||
|
let _ = logger.call(Ok(msg), ThreadsafeFunctionCallMode::NonBlocking);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flush(&self) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import log from "electron-log/main";
|
|||||||
|
|
||||||
import { LogLevelType } from "@bitwarden/common/platform/enums/log-level-type.enum";
|
import { LogLevelType } from "@bitwarden/common/platform/enums/log-level-type.enum";
|
||||||
import { ConsoleLogService as BaseLogService } from "@bitwarden/common/platform/services/console-log.service";
|
import { ConsoleLogService as BaseLogService } from "@bitwarden/common/platform/services/console-log.service";
|
||||||
|
import { logging } from "@bitwarden/desktop-napi";
|
||||||
|
|
||||||
import { isDev } from "../../utils";
|
import { isDev } from "../../utils";
|
||||||
|
|
||||||
@@ -30,6 +31,29 @@ export class ElectronLogMainService extends BaseLogService {
|
|||||||
ipcMain.handle("ipc.log", (_event, { level, message, optionalParams }) => {
|
ipcMain.handle("ipc.log", (_event, { level, message, optionalParams }) => {
|
||||||
this.write(level, message, ...optionalParams);
|
this.write(level, message, ...optionalParams);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
logging.initNapiLog((error, level, message) => this.writeNapiLog(level, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
private writeNapiLog(level: logging.LogLevel, message: string) {
|
||||||
|
let levelType: LogLevelType;
|
||||||
|
|
||||||
|
switch (level) {
|
||||||
|
case logging.LogLevel.Debug:
|
||||||
|
levelType = LogLevelType.Debug;
|
||||||
|
break;
|
||||||
|
case logging.LogLevel.Warn:
|
||||||
|
levelType = LogLevelType.Warning;
|
||||||
|
break;
|
||||||
|
case logging.LogLevel.Error:
|
||||||
|
levelType = LogLevelType.Error;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
levelType = LogLevelType.Info;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.write(levelType, "[NAPI] " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
write(level: LogLevelType, message?: any, ...optionalParams: any[]) {
|
write(level: LogLevelType, message?: any, ...optionalParams: any[]) {
|
||||||
|
|||||||
@@ -5,6 +5,14 @@ jest.mock("electron", () => ({
|
|||||||
ipcMain: { handle: jest.fn(), on: jest.fn() },
|
ipcMain: { handle: jest.fn(), on: jest.fn() },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
jest.mock("@bitwarden/desktop-napi", () => {
|
||||||
|
return {
|
||||||
|
logging: {
|
||||||
|
initNapiLog: jest.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
describe("ElectronLogMainService", () => {
|
describe("ElectronLogMainService", () => {
|
||||||
it("sets dev based on electron method", () => {
|
it("sets dev based on electron method", () => {
|
||||||
process.env.ELECTRON_IS_DEV = "1";
|
process.env.ELECTRON_IS_DEV = "1";
|
||||||
|
|||||||
Reference in New Issue
Block a user