Skip to content
Extraits de code Groupes Projets
Vérifiée Valider e72e8671 rédigé par Kubat's avatar Kubat
Parcourir les fichiers

RUST: Logging from rust will call the C logging functions and write to stderr...

RUST: Logging from rust will call the C logging functions and write to stderr and log files like the rest of the code
parent 30f93670
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
#if !defined(LIBLEKTOR_RS_LOGING___)
#define LIBLEKTOR_RS_LOGING___
#if defined(__cplusplus)
extern "C" {
#endif
void lektor_init_rust_logging(void);
#if defined(__cplusplus)
}
#endif
#endif // LIBLEKTOR_RS_LOGING___
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <lektor/logfile.h> #include <lektor/logfile.h>
#include <liblektor-rs/database.h> #include <liblektor-rs/database.h>
#include <liblektor-rs/loging.h>
#include <wait.h> #include <wait.h>
#include <spawn.h> #include <spawn.h>
...@@ -105,6 +106,7 @@ main(int argc, char *argv[]) ...@@ -105,6 +106,7 @@ main(int argc, char *argv[])
struct lkt_logfile *logfile = lkt_logfile_new(srv.db); struct lkt_logfile *logfile = lkt_logfile_new(srv.db);
lkt_set_log_logfile(logfile); lkt_set_log_logfile(logfile);
lektor_init_rust_logging();
/* Read the configuration. We already know that the config is valid */ /* Read the configuration. We already know that the config is valid */
database_config_get_int(srv.db, "player", "autoclear", &autoclear); database_config_get_int(srv.db, "player", "autoclear", &autoclear);
......
...@@ -8,6 +8,7 @@ crate-type = ["staticlib"] ...@@ -8,6 +8,7 @@ crate-type = ["staticlib"]
[dependencies] [dependencies]
log.workspace = true log.workspace = true
lazy_static.workspace = true
lektor_c_compat = { path = "../lektor_c_compat", features = ["c_types"] } lektor_c_compat = { path = "../lektor_c_compat", features = ["c_types"] }
lektor_repo = { path = "../lektor_repo" } lektor_repo = { path = "../lektor_repo" }
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#![allow(unused_variables)] #![allow(unused_variables)]
pub mod db; pub mod db;
pub mod loging;
pub mod repo; pub mod repo;
pub(crate) use lektor_c_compat::{c::*, *}; pub(crate) use lektor_c_compat::{c::*, *};
......
use lektor_c_compat::*;
use log::{Level, Metadata, Record};
use std::{convert::Into, fmt::format, sync::atomic::AtomicU8};
enum LogLevel {
Debug,
Info,
Warning,
Error,
}
struct CLogger {
level: AtomicU8,
}
lazy_static::lazy_static! {
static ref LOGGER: CLogger = CLogger {
level: AtomicU8::new(Into::<c_int>::into(LogLevel::Warning) as u8),
};
}
impl log::Log for CLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
use LogLevel::*;
let lvl = LogLevel::try_from(LOGGER.level.load(std::sync::atomic::Ordering::SeqCst))
.unwrap_or_default();
matches!(
(lvl, LogLevel::from(metadata.level())),
(Debug, _)
| (Info, Info | Warning | Error)
| (Warning, Warning | Error)
| (Error, Error)
)
}
fn log(&self, record: &Record) {
if self.enabled(record.metadata()) {
unsafe {
___lkt_log(
LogLevel::from(record.metadata().level()).into(),
(format!("{}\0", record.target())).as_ptr() as *const _,
b"*unknown-func*\0".as_ptr() as *const _,
(format!("{}\0", record.file_static().unwrap_or("..."))).as_ptr() as *const _,
record.line().unwrap_or_default() as i64,
b"%s\0".as_ptr() as *const _,
match record.args().as_str() {
Some(str) => format!("{str}\0"),
None => format!("{}\0", format(*record.args())),
},
)
}
}
}
fn flush(&self) {}
}
impl Default for LogLevel {
fn default() -> Self {
LogLevel::Info
}
}
impl From<Level> for LogLevel {
fn from(lvl: Level) -> Self {
use LogLevel::*;
match lvl {
Level::Error => Error,
Level::Warn => Warning,
Level::Info => Info,
Level::Debug | Level::Trace => Debug,
}
}
}
impl From<LogLevel> for u8 {
fn from(lvl: LogLevel) -> Self {
match lvl {
LogLevel::Debug => 4,
LogLevel::Info => 3,
LogLevel::Warning => 2,
LogLevel::Error => 1,
}
}
}
impl From<LogLevel> for c_int {
fn from(lvl: LogLevel) -> Self {
(lvl as u8) as c_int
}
}
impl TryFrom<c_int> for LogLevel {
type Error = ();
fn try_from(value: c_int) -> Result<Self, <LogLevel as TryFrom<c_int>>::Error> {
use LogLevel::*;
match value {
1 => Ok(Error),
2 => Ok(Warning),
3 => Ok(Info),
4 => Ok(Debug),
_ => Err(()),
}
}
}
impl TryFrom<u8> for LogLevel {
type Error = ();
fn try_from(value: u8) -> Result<Self, <LogLevel as TryFrom<c_int>>::Error> {
TryFrom::<c_int>::try_from(value as c_int)
}
}
extern "C" {
fn ___lkt_log(
log_level: c_int,
section: *const c_char,
function: *const c_char,
file: *const c_char,
line: i64,
fmt: *const c_char,
...
);
fn lkt_get_log_level() -> c_int;
}
#[no_mangle]
pub extern "C" fn lektor_init_rust_logging() {
LOGGER.level.store(
Into::<u8>::into(LogLevel::try_from(unsafe { lkt_get_log_level() }).unwrap_or_default()),
std::sync::atomic::Ordering::SeqCst,
);
if let Err(err) = log::set_logger(&*LOGGER) {
panic!("failed to set logger: {err}")
}
}
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter