github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/src/metrics/mod.rs (about)

     1  // Copyright 2018 Intel Corporation
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  // ------------------------------------------------------------------------------
    15  
    16  use std::collections::HashMap;
    17  
    18  use cpython::{NoArgs, ObjectProtocol, PyDict, PyModule, PyObject, Python, ToPyObject};
    19  
    20  pub fn get_collector<S: AsRef<str>>(name: S) -> MetricsCollectorHandle {
    21      let gil = Python::acquire_gil();
    22      let py = gil.python();
    23      let py_metrics = py.import("sawtooth_validator.metrics")
    24          .expect("Failed to import sawtooth_validator.metrics module");
    25      let py_collector = py_metrics
    26          .call(py, "get_collector", (name.as_ref(),), None)
    27          .expect("Failed to call metrics.get_collector()");
    28      MetricsCollectorHandle {
    29          py_collector,
    30          py_metrics,
    31      }
    32  }
    33  
    34  pub enum Level {
    35      Debug,
    36      Info,
    37      Perf,
    38  }
    39  
    40  impl Default for Level {
    41      fn default() -> Self {
    42          Level::Info
    43      }
    44  }
    45  
    46  fn into_level_str(level: Level) -> &'static str {
    47      use self::Level::*;
    48      match level {
    49          Debug => "DEBUG",
    50          Info => "INFO",
    51          Perf => "PERF",
    52      }
    53  }
    54  
    55  pub struct MetricsCollectorHandle {
    56      py_collector: PyObject,
    57      py_metrics: PyModule,
    58  }
    59  
    60  impl MetricsCollectorHandle {
    61      pub fn counter<S: AsRef<str>>(
    62          &self,
    63          metric_name: S,
    64          level: Option<Level>,
    65          tags: Option<HashMap<String, String>>,
    66      ) -> Counter {
    67          Counter {
    68              py_counter: self.create_metric("counter", metric_name, level, tags),
    69          }
    70      }
    71  
    72      pub fn gauge<S: AsRef<str>>(
    73          &self,
    74          metric_name: S,
    75          level: Option<Level>,
    76          tags: Option<HashMap<String, String>>,
    77      ) -> Gauge {
    78          Gauge {
    79              py_gauge: self.create_metric("gauge", metric_name, level, tags),
    80          }
    81      }
    82  
    83      pub fn timer<S: AsRef<str>>(
    84          &self,
    85          metric_name: S,
    86          level: Option<Level>,
    87          tags: Option<HashMap<String, String>>,
    88      ) -> Timer {
    89          Timer {
    90              py_timer: self.create_metric("timer", metric_name, level, tags),
    91          }
    92      }
    93  
    94      fn create_metric<S: AsRef<str>>(
    95          &self,
    96          metric_type: &str,
    97          metric_name: S,
    98          level: Option<Level>,
    99          tags: Option<HashMap<String, String>>,
   100      ) -> PyObject {
   101          let gil = Python::acquire_gil();
   102          let py = gil.python();
   103  
   104          let py_level = self.py_metrics
   105              .get(py, into_level_str(level.unwrap_or(Default::default())))
   106              .expect("Failed to get metric level");
   107          let py_tags: PyDict = tags.unwrap_or_else(|| HashMap::new()).into_py_object(py);
   108          let kwargs = PyDict::new(py);
   109          kwargs.set_item(py, "level", py_level).unwrap();
   110          kwargs.set_item(py, "tags", py_tags).unwrap();
   111  
   112          self.py_collector
   113              .call_method(py, metric_type, (metric_name.as_ref(),), Some(&kwargs))
   114              .expect("Failed to create new metric")
   115      }
   116  }
   117  
   118  pub struct Gauge {
   119      py_gauge: PyObject,
   120  }
   121  
   122  impl Gauge {
   123      pub fn set_value<T: ToPyObject>(&mut self, value: T) {
   124          let gil = Python::acquire_gil();
   125          let py = gil.python();
   126          self.py_gauge
   127              .call_method(py, "set_value", (value,), None)
   128              .expect("Failed to call Gauge.set_value()");
   129      }
   130  }
   131  
   132  pub struct Counter {
   133      py_counter: PyObject,
   134  }
   135  
   136  impl Counter {
   137      pub fn inc(&mut self) {
   138          let gil = Python::acquire_gil();
   139          let py = gil.python();
   140          self.py_counter
   141              .call_method(py, "inc", NoArgs, None)
   142              .expect("Failed to call Counter.inc()");
   143      }
   144  
   145      pub fn inc_n(&mut self, value: usize) {
   146          let gil = Python::acquire_gil();
   147          let py = gil.python();
   148          self.py_counter
   149              .call_method(py, "inc", (value,), None)
   150              .expect("Failed to call Counter.inc()");
   151      }
   152  
   153      pub fn dec(&mut self) {
   154          let gil = Python::acquire_gil();
   155          let py = gil.python();
   156          self.py_counter
   157              .call_method(py, "dec", NoArgs, None)
   158              .expect("Failed to call Counter.dec()");
   159      }
   160  }
   161  
   162  pub struct Timer {
   163      py_timer: PyObject,
   164  }
   165  
   166  impl Timer {
   167      pub fn time(&mut self) -> TimerHandle {
   168          let gil = Python::acquire_gil();
   169          let py = gil.python();
   170          TimerHandle {
   171              py_timer_ctx: self.py_timer
   172                  .call_method(py, "time", NoArgs, None)
   173                  .expect("Failed to call Timer.time()"),
   174          }
   175      }
   176  }
   177  
   178  pub struct TimerHandle {
   179      py_timer_ctx: PyObject,
   180  }
   181  
   182  impl Drop for TimerHandle {
   183      fn drop(&mut self) {
   184          let gil = Python::acquire_gil();
   185          let py = gil.python();
   186          self.py_timer_ctx
   187              .call_method(py, "stop", NoArgs, None)
   188              .expect("Failed to call TimerContext.stop()");
   189      }
   190  }