[英]Java/Rust logging bridge
I have a Java program that uses JNI to call a Rust library.我有一个 Java 程序,它使用 JNI 调用 Rust 库。 In the rust code, I have calls to info!
在 rust 代码中,我有电话咨询info!
which do not appear in the output.没有出现在 output 中。 I am 99% positive this is because I am not initializing the Rust logging system.我 99% 肯定这是因为我没有初始化 Rust 日志系统。
When I had a similar problem in Python code calling Rust code, there was a module that I added which did the work to connect the Rust logging system to the python logger. When I had a similar problem in Python code calling Rust code, there was a module that I added which did the work to connect the Rust logging system to the python logger.
Is there a similar bridge for Rust and Java? Rust 和 Java 是否有类似的桥接?
I am using slf4j
in Java and log::info
in Rust.我在 Java 中使用slf4j
,在 Rust 中使用log::info
。
I searched for an bridge but the closest I found was how to call Rust from Java.我搜索了一座桥,但我找到的最接近的是如何从 Java 调用 Rust。
The log
library provides only a mechanism for passing log messages to a global hook. log
库仅提供一种将日志消息传递到全局挂钩的机制。 Something must call log::set_logger()
with a function that does something with the messages.必须使用 function 调用log::set_logger()
来处理消息。 There are a variety of libraries you can use for this purpose ;有多种库可以用于此目的; if you want to hook up your log
logging to slf4j
you will need to find or write code that does that combination specifically.如果您想将log
记录连接到slf4j
,您将需要查找或编写专门执行该组合的代码。 (I don't know much of anything about JNI+Rust so I can't say whether one exists already.) (我对 JNI+Rust 知之甚少,所以我不能说是否已经存在。)
use std::sync::Arc;
use log::{LevelFilter, Level};
pub type LogCallbackType = Arc<dyn Fn(Level, String) + Send + Sync>;
pub struct SimpleLogger {
callback: LogCallbackType,
level: LevelFilter,
}
impl SimpleLogger {
pub fn init(level: LevelFilter, callback: LogCallbackType) {
let message = std::format!("Initialize logging to {}", &level);
callback(Level::Debug, message);
log::set_boxed_logger(Box::new(SimpleLogger { callback, level }))
.map(|()| log::set_max_level(level));
}
use std::os::raw::c_char;
pub type NativeString = *const c_char;
pub type ExternLogCallbackType = Option<extern "C" fn(u32, NativeString)>;
#[no_mangle]
pub extern fn init_logging(level: u32, callback: ExternLogCallbackType) {
if !callback.is_none() {
let callback = callback.unwrap();
let level_filter = SimpleLogger::u32_to_level_filter(level);
SimpleLogger::init(level_filter, Arc::new(move |level, msg| {
callback(level as u32, msg.as_ptr());
}))
}
}
public static class LogCallback implements Callback {
public static final Logger LOGGER = LoggerFactory.getLogger("myrustliblog");
public void callback(int level, String message) {
switch (level) {
case 0:
break;
case 1:
LOGGER.error(message);
break;
case 2:
LOGGER.warn(message);
break;
case 3:
LOGGER.info(message);
break;
case 4:
LOGGER.debug(message);
break;
case 5:
LOGGER.trace(message);
break;
default:
LOGGER.trace(message);
break;
}
}
}
public interface MyNativeInterface extends Library {
//...other stuff ...
String init_logging(int level, LogCallback callback);
//...
}
static final LogCallback LOG_CALLBACK = new LogCallback();
public static void initLogging(org.slf4j.event.Level level) {
int iLevel = 0;
switch (level) {
case ERROR:
iLevel = 1;
break;
case WARN:
iLevel = 2;
break;
case INFO:
iLevel = 3;
break;
case DEBUG:
iLevel = 4;
break;
case TRACE:
iLevel = 5;
break;
}
_myInterfaceJnaInstance.init_logging(iLevel, LOG_CALLBACK);
}
Notes:笔记:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.