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  }