github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/src/pylogger.rs (about) 1 /* 2 * Copyright 2018 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * ------------------------------------------------------------------------------ 16 */ 17 18 use cpython::{ObjectProtocol, PyDict, PyErr, PyModule, PyObject, PyResult, PyTuple, Python, 19 PythonObject, ToPyObject}; 20 use log; 21 use log::{Level, Log, Metadata, Record, SetLoggerError}; 22 23 pub fn set_up_logger(verbosity: u64, py: Python) { 24 let verbosity_level: Level = determine_log_level(verbosity); 25 26 PyLogger::init(verbosity_level, py).expect("Failed to set logger"); 27 28 let server_log = py.import("sawtooth_validator.server.log") 29 .map_err(|err| err.print(py)) 30 .unwrap(); 31 32 server_log 33 .call(py, "init_console_logging", (verbosity,), None) 34 .map_err(|err| err.print(py)) 35 .unwrap(); 36 37 warn!("Started logger at level {}", verbosity_level); 38 } 39 40 #[no_mangle] 41 pub extern "C" fn pylogger_init(verbosity: usize) { 42 let gil = Python::acquire_gil(); 43 let py = gil.python(); 44 PyLogger::init(determine_log_level(verbosity as u64), py) 45 .expect("Failed to initialize PyLogger"); 46 } 47 48 pub fn exception(py: Python, msg: &str, err: PyErr) { 49 let logger = PyLogger::new(py).expect("Failed to create new PyLogger"); 50 logger.exception(py, msg, err); 51 } 52 53 struct PyLogger { 54 logger: PyObject, 55 logging: PyModule, 56 } 57 58 impl PyLogger { 59 fn new(py: Python) -> PyResult<Self> { 60 let logging = py.import("logging")?; 61 let logger = logging.call(py, "getLogger", PyTuple::new(py, &[]), None)?; 62 Ok(PyLogger { logger, logging }) 63 } 64 65 fn init(verbosity: Level, py: Python) -> Result<(), SetLoggerError> { 66 let logger = PyLogger::new(py).unwrap(); 67 68 log::set_boxed_logger(Box::new(logger))?; 69 70 log::set_max_level(verbosity.to_level_filter()); 71 72 Ok(()) 73 } 74 75 pub fn exception(&self, py: Python, msg: &str, mut err: PyErr) { 76 let kwargs = PyDict::new(py); 77 let exc_info = ( 78 err.get_type(py), 79 err.instance(py), 80 err.ptraceback.unwrap_or_else(|| py.None()), 81 ); 82 kwargs.set_item(py, "exc_info", exc_info).unwrap(); 83 self.logger 84 .call_method(py, "error", (msg,), Some(&kwargs)) 85 .unwrap(); 86 } 87 } 88 89 fn determine_log_level(verbosity: u64) -> Level { 90 match verbosity { 91 0 => Level::Warn, 92 1 => Level::Info, 93 _ => Level::Debug, 94 } 95 } 96 97 fn into_level_string(level: Level) -> &'static str { 98 match level { 99 Level::Error => "ERROR", 100 Level::Warn => "WARN", 101 Level::Info => "INFO", 102 Level::Debug => "DEBUG", 103 Level::Trace => "DEBUG", 104 } 105 } 106 107 fn into_level_method(level: Level) -> &'static str { 108 match level { 109 Level::Error => "error", 110 Level::Warn => "warn", 111 Level::Info => "info", 112 Level::Debug => "debug", 113 Level::Trace => "debug", 114 } 115 } 116 117 impl Log for PyLogger { 118 fn enabled(&self, metadata: &Metadata) -> bool { 119 let gil = Python::acquire_gil(); 120 let py = gil.python(); 121 122 let level = into_level_string(metadata.level()); 123 let pylevel = self.logging.get(py, level).unwrap(); 124 125 self.logger 126 .call_method(py, "isEnabledFor", PyTuple::new(py, &[pylevel]), None) 127 .unwrap() 128 .extract(py) 129 .unwrap() 130 } 131 132 fn log(&self, record: &Record) { 133 let gil = Python::acquire_gil(); 134 let py = gil.python(); 135 136 if !self.enabled(record.metadata()) { 137 return; 138 } 139 140 let method = into_level_method(record.level()); 141 let record = format!( 142 "[{}: {}] {}", 143 record.file().unwrap_or("unknown file"), 144 record.line().unwrap_or(0), 145 record.args() 146 ); 147 148 self.logger 149 .call_method( 150 py, 151 method, 152 PyTuple::new(py, &[record.to_py_object(py).into_object()]), 153 None, 154 ) 155 .unwrap(); 156 } 157 158 fn flush(&self) { 159 let gil = Python::acquire_gil(); 160 let py = gil.python(); 161 self.logger 162 .call_method(py, "flush", PyTuple::new(py, &[]), None) 163 .unwrap(); 164 } 165 }