use log::{logger, Level, MetadataBuilder, Record};
use pyo3::prelude::*;
pub fn register() {
Python::attach(|py| {
setup_logging(py)
})
.unwrap();
}
#[pyfunction]
fn host_log(record: &Bound<'_, PyAny>) -> PyResult<()> {
let level = record.getattr("levelno")?;
let message = record.getattr("getMessage")?.call0()?.to_string();
let pathname = record.getattr("pathname")?.to_string();
let lineno = record
.getattr("lineno")?
.to_string()
.parse::<u32>()
.unwrap();
let _logger_name = record.getattr("name")?.to_string();
let error_metadata = if level.ge(40u8)? {
MetadataBuilder::new()
.target("angreal")
.level(Level::Error)
.build()
} else if level.ge(30u8)? {
MetadataBuilder::new()
.target("angreal")
.level(Level::Warn)
.build()
} else if level.ge(20u8)? {
MetadataBuilder::new()
.target("angreal")
.level(Level::Info)
.build()
} else if level.ge(10u8)? {
MetadataBuilder::new()
.target("angreal")
.level(Level::Debug)
.build()
} else {
MetadataBuilder::new()
.target("angreal")
.level(Level::Trace)
.build()
};
logger().log(
&Record::builder()
.metadata(error_metadata)
.args(format_args!("{}", &message))
.line(Some(lineno))
.file(Some("angreal task"))
.module_path(Some(&pathname))
.build(),
);
Ok(())
}
pub fn setup_logging(py: Python) -> PyResult<()> {
let logging = py.import("logging")?;
logging.setattr("host_log", wrap_pyfunction!(host_log, &logging)?)?;
py.run(
c"
class HostHandler(Handler):
def __init__(self, level=0):
super().__init__(level=level)
def emit(self, record):
host_log(record)
oldBasicConfig = basicConfig
def basicConfig(*pargs, **kwargs):
if 'handlers' not in kwargs:
kwargs['handlers'] = [HostHandler()]
return oldBasicConfig(*pargs, **kwargs)
",
Some(&logging.dict()),
None,
)?;
let all = logging.index()?;
all.append("HostHandler")?;
Ok(())
}