Skip to content

Commit 8de4536

Browse files
committed
Allow the specficiation of a logging prefix when setting up a logger
1 parent 7e5e5cd commit 8de4536

4 files changed

Lines changed: 49 additions & 5 deletions

File tree

examples/hello_world/hw.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77
logging.basicConfig(format=FORMAT)
88
logging.getLogger().setLevel(logging.INFO)
99
logging.info("Test 1")
10+
hello_world.enable_logging()
1011
hello_world.log_hello()

examples/hello_world/hw_prefix.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env python
2+
3+
import logging
4+
import hello_world
5+
6+
FORMAT = '%(levelname)s %(name)s %(asctime)-15s %(filename)s:%(lineno)d %(message)s'
7+
logger = logging.getLogger('test')
8+
logger.setLevel(logging.INFO)
9+
handler = logging.StreamHandler()
10+
handler.setFormatter(logging.Formatter(FORMAT))
11+
logger.addHandler(handler)
12+
13+
hello_world.enable_logging(prefix="test")
14+
hello_world.log_hello()

examples/hello_world/src/lib.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@ use pyo3::prelude::*;
33
use pyo3::wrap_pyfunction;
44
use pyo3_log::{Caching, Logger};
55

6+
#[pyfunction]
7+
#[pyo3(signature = (prefix=None))]
8+
fn enable_logging(py: Python<'_>, prefix: Option<String>) -> PyResult<()> {
9+
let mut logger = Logger::new(py, Caching::LoggersAndLevels)?;
10+
logger = if let Some(prefix) = prefix {
11+
logger.prefix(&prefix)
12+
} else {
13+
logger
14+
};
15+
16+
let _ = logger.install();
17+
Ok(())
18+
}
19+
620
#[pyfunction]
721
fn log_hello() {
822
trace!("xyz");
@@ -13,10 +27,8 @@ fn log_hello() {
1327
}
1428

1529
#[pymodule]
16-
fn hello_world(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
17-
let _ = Logger::new(py, Caching::LoggersAndLevels)?
18-
.install();
19-
30+
fn hello_world(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
31+
m.add_wrapped(wrap_pyfunction!(enable_logging))?;
2032
m.add_wrapped(wrap_pyfunction!(log_hello))?;
2133

2234
Ok(())

src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,9 @@ pub struct Logger {
303303
/// full paths, with `::` separaters (eg. before converting them from Rust to Python).
304304
filters: HashMap<String, LevelFilter>,
305305

306+
/// The prefix to prepend to all log targets
307+
prefix: Option<String>,
308+
306309
/// The imported Python `logging` module.
307310
logging: Py<PyModule>,
308311

@@ -329,6 +332,7 @@ impl Logger {
329332
Ok(Self {
330333
top_filter: LevelFilter::Debug,
331334
filters: HashMap::new(),
335+
prefix: None,
332336
logging: logging.into(),
333337
caching,
334338
cache: Default::default(),
@@ -401,6 +405,15 @@ impl Logger {
401405
self
402406
}
403407

408+
/// Sets a prefix to prepend to log targets before sending log messages to Python.
409+
///
410+
/// This allows for Python-side arrangements where logging configurations are only
411+
/// attached to logging names other than the root.
412+
pub fn prefix(mut self, prefix: &str) -> Self {
413+
self.prefix = Some(prefix.replace("::", "."));
414+
self
415+
}
416+
404417
/// Finds a node in the cache.
405418
///
406419
/// The hierarchy separator is `::`.
@@ -433,7 +446,11 @@ impl Logger {
433446
) -> PyResult<Option<Py<PyAny>>> {
434447
let msg = format!("{}", record.args());
435448
let log_level = map_level(record.level());
436-
let target = record.target().replace("::", ".");
449+
let mut target = record.target().replace("::", ".");
450+
target = match &self.prefix {
451+
Some(prefix) => format!("{}.{}", prefix, target),
452+
None => target
453+
};
437454
let cached_logger = cache
438455
.as_ref()
439456
.and_then(|node| node.local.as_ref())

0 commit comments

Comments
 (0)