blob: 3a0cfd6b03ca2e8937648e202a30cf7a81191f7d [file] [log] [blame]
Jeff Vander Stoep761577d2020-10-14 15:21:00 +02001// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
2
3use std::ffi::CStr;
4
5use crate::grpc_sys::{self, gpr_log_func_args, gpr_log_severity};
6use log::{self, Level, LevelFilter, Record};
7
8#[inline]
9fn severity_to_log_level(severity: gpr_log_severity) -> Level {
10 match severity {
11 gpr_log_severity::GPR_LOG_SEVERITY_DEBUG => Level::Debug,
12 gpr_log_severity::GPR_LOG_SEVERITY_INFO => Level::Info,
13 gpr_log_severity::GPR_LOG_SEVERITY_ERROR => Level::Error,
14 }
15}
16
17extern "C" fn delegate(c_args: *mut gpr_log_func_args) {
18 let args = unsafe { &*c_args };
19 let level = severity_to_log_level(args.severity);
20 if !log_enabled!(level) {
21 return;
22 }
23
24 // can't panic.
25 let file_str = unsafe { CStr::from_ptr(args.file).to_str().unwrap() };
26 let line = args.line as u32;
27
28 let msg = unsafe { CStr::from_ptr(args.message).to_string_lossy() };
29 log::logger().log(
30 &Record::builder()
31 .args(format_args!("{}", msg))
32 .level(level)
33 .file(file_str.into())
34 .line(line.into())
35 .module_path(module_path!().into())
36 .build(),
37 );
38}
39
40/// Redirect grpc log to rust's log implementation.
41pub fn redirect_log() {
42 let level = match log::max_level() {
43 LevelFilter::Off => unsafe {
44 // disable log.
45 grpc_sys::gpr_set_log_function(None);
46 return;
47 },
48 LevelFilter::Error | LevelFilter::Warn => gpr_log_severity::GPR_LOG_SEVERITY_ERROR,
49 LevelFilter::Info => gpr_log_severity::GPR_LOG_SEVERITY_INFO,
50 LevelFilter::Debug | LevelFilter::Trace => gpr_log_severity::GPR_LOG_SEVERITY_DEBUG,
51 };
52
53 unsafe {
54 grpc_sys::gpr_set_log_verbosity(level);
55 grpc_sys::gpr_set_log_function(Some(delegate));
56 }
57}