Rust日志学习(四)——simplelog
来源:互联网 发布:淘宝冷光美白仪有用么 编辑:程序博客网 时间:2024/06/16 14:10
simplelog——A simple and easy-to-use logging facility for Rust’s log crate.
simplelog的目标不是提供非常丰富的特性,也不是提供最佳日志方案,而是旨在提供简单易用的适合中小规模工程的日志方案。原文如下:
simplelog does not aim to provide a rich set of features, nor to provide the best logging solution. It aims to be a maintainable, easy to integrate facility for small to medium sized projects, that find env_logger to be somewhat lacking in features. In those cases simplelog should provide an easy alternative.
Github地址:https://github.com/drakulix/simplelog.rs
simplelog提供了一些logging facilities如下所示(也是simplelog中最重要的概念):
- SimpleLogger—— very basic logger that logs to stderr/out, should never fail
- TermLogger ——advanced terminal logger, that splits to stderr/out and has color support (can be excluded on unsupported platforms)
- WriteLogger ——logs to a given struct implementing Write. e.g. a file
- CombinedLogger ——can be used to form combinations of the above loggers
对应的,simplelog中4个重要的structs:
分析SimpleLogger源代码如下:
//! Module providing the SimpleLogger Implementationuse std::io::{stderr, stdout};use log::{LogLevel, LogLevelFilter, LogMetadata, LogRecord, SetLoggerError, set_logger, Log};use ::{Config, SharedLogger};use super::logging::try_log;/// The SimpleLogger struct. Provides a very basic Logger implementationpub struct SimpleLogger { level: LogLevelFilter, config: Config,}impl SimpleLogger { /// init function. Globally initializes the SimpleLogger as the one and only used log facility. /// /// Takes the desired `LogLevel` and `Config` as arguments. They cannot be changed later on. /// Fails if another Logger was already initialized. pub fn init(log_level: LogLevelFilter, config: Config) -> Result<(), SetLoggerError> { set_logger(|max_log_level| { max_log_level.set(log_level.clone()); SimpleLogger::new(log_level, config) }) } /// allows to create a new logger, that can be independently used, no matter what is globally set. /// /// no macros are provided for this case and you probably /// dont want to use this function, but `init()`, if you dont want to build a `CombinedLogger`. /// /// Takes the desired `LogLevel` and `Config` as arguments. They cannot be changed later on. pub fn new(log_level: LogLevelFilter, config: Config) -> Box<SimpleLogger> { Box::new(SimpleLogger { level: log_level, config: config }) }}//实现Log Traitimpl Log for SimpleLogger { fn enabled(&self, metadata: &LogMetadata) -> bool { metadata.level() <= self.level } fn log(&self, record: &LogRecord) { if self.enabled(record.metadata()) { match record.level() { LogLevel::Error => { let stderr = stderr(); let mut stderr_lock = stderr.lock(); let _ = try_log(&self.config, record, &mut stderr_lock); }, _ => { let stdout = stdout(); let mut stdout_lock = stdout.lock(); let _ = try_log(&self.config, record, &mut stdout_lock); } } } }}//实现SharedLogger Trait impl SharedLogger for SimpleLogger { fn level(&self) -> LogLevelFilter { self.level } fn config(&self) -> Option<&Config> { Some(&self.config) } fn as_log(self: Box<Self>) -> Box<Log> { Box::new(*self) }}
SimpleLogger是代码最简单的一个,其他Structs源代码参看:https://github.com/Drakulix/simplelog.rs/tree/master/src/loggers
另外,因为下面的用法示例用到了CombinedLogger,所以把它的源代码也列出来学习一下:
//! Module providing the CombinedLogger Implementationuse log::{LogLevelFilter, LogMetadata, LogRecord, SetLoggerError, set_logger, Log};use ::{SharedLogger, Config};/// The CombinedLogger struct. Provides a Logger implementation that proxies multiple Loggers as one.////// The purpose is to allow multiple Loggers to be set globallypub struct CombinedLogger { level: LogLevelFilter, logger: Vec<Box<SharedLogger>>,}impl CombinedLogger { /// init function. Globally initializes the CombinedLogger as the one and only used log facility. /// /// Takes all used Loggers as a Vector argument. None of those Loggers should already be set globally. /// /// All loggers need to implement `log::Log` and `logger::SharedLogger` and need to provide a way to be /// initialized without calling `set_logger`. All loggers of this library provide a `new(..)`` method /// for that purpose. /// Fails if another logger is already set globally. pub fn init(logger: Vec<Box<SharedLogger>>) -> Result<(), SetLoggerError> { set_logger(|max_log_level| { let result = CombinedLogger::new(logger); max_log_level.set(result.level()); result }) } /// allows to create a new logger, that can be independently used, no matter whats globally set. /// /// no macros are provided for this case and you probably /// dont want to use this function, but `init()`, if you dont want to build a `CombinedLogger`. /// /// Takes all used loggers as a Vector argument. The log level is automatically determined by the /// lowest log level used by the given loggers. /// /// All loggers need to implement log::Log. pub fn new(logger: Vec<Box<SharedLogger>>) -> Box<CombinedLogger> { let mut log_level = LogLevelFilter::Off; for log in &logger { if log_level < log.level() { log_level = log.level(); } } Box::new(CombinedLogger { level: log_level, logger: logger }) }}//实现Log Traitimpl Log for CombinedLogger { fn enabled(&self, metadata: &LogMetadata) -> bool { metadata.level() <= self.level } fn log(&self, record: &LogRecord) { if self.enabled(record.metadata()) { for log in &self.logger { log.log(record); } } }}//实现SharedLogger Traitimpl SharedLogger for CombinedLogger { fn level(&self) -> LogLevelFilter { self.level } fn config(&self) -> Option<&Config> { None } fn as_log(self: Box<Self>) -> Box<Log> { Box::new(*self) }}
这里面有个Config structs,对应源代码如下:
use log::LogLevel;/// Configuration for the Loggers////// All loggers print the message in the following form:/// `00:00:00 [LEVEL] crate::module: [lib.rs::100] your_message`/// Every space delimited part except the actual message is optional.////// Pass this struct to your logger to change when these information shall/// be logged. Every part can be enabled for a specific LogLevel and is then/// automatically enable for all lower levels as well.////// The Result is that the logging gets more detailed the more verbose it gets./// E.g. to have one part shown always use `LogLevel::Error`. But if you/// want to show the source line only on `Trace` use that./// Passing `None` will completely disable the part.#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub struct Config{ ///At which level and below the current time shall be logged pub time: Option<LogLevel>, ///At which level and below the level itself shall be logged pub level: Option<LogLevel>, ///At which level and below the target shall be logged pub target: Option<LogLevel>, ///At which level and below a source code reference shall be logged pub location: Option<LogLevel>,}impl Default for Config { fn default() -> Config { Config { time: Some(LogLevel::Error), level: Some(LogLevel::Error), target: Some(LogLevel::Debug), location: Some(LogLevel::Trace), } }}
用法示例:
#[macro_use]extern crate log;extern crate simplelog;fn main() { simplelog_fn();}#[warn(dead_code)]fn simplelog_fn(){ use std::fs::File; use simplelog::*; CombinedLogger::init( vec![ TermLogger::new(LogLevelFilter::Warn, Config::default()).unwrap(),//terminal logger WriteLogger::new(LogLevelFilter::Info, Config::default(), File::create("my_rust_binary.log").unwrap()),//记录日志到"*.log"文件中 ] ).unwrap(); error!("Bright red error"); info!("This only appears in the log file"); debug!("This level is currently not enabled for any logger"); }
运行结果:
终端显示如下:
日志文件内容如下:
- Rust日志学习(四)——simplelog
- Rust日志学习(一)—— 初识Rust log
- Rust日志学习(二)——env_logger
- Rust日志学习(三)——simple_logger
- Rust日志学习(五)—— log4rs
- Rust学习记录——后缀计算器
- commons.logging1.1.1源代码研究(3)-- 日志器Log接口,SimpleLog实现
- node.js学习日志(四)—— REDIS
- JBPM学习日志(四)
- Linux学习日志(四)
- 使用commons.logging中的SimpleLog显示调试和日志信息
- Rust语言学习笔记(1)
- Rust语言学习笔记(2)
- Rust语言学习笔记(3)
- 黑马程序员——黑马学习日志之十五 IO流(四)
- 黑马程序员——黑马学习日志之二十二 Java高新技术(四)
- aix学习日志(四)之系统管理!
- apache mina 学习(四)-----日志配置
- Sublime text3常用插件
- 用AVCodecParameters代替AVCodecContext
- git 撤销merge操作 (是merge操作,不是push)
- GIthub访问速度慢的解决方法
- 【算法】有向无环图
- Rust日志学习(四)——simplelog
- 文章标题
- catkin简析
- linux基础知识及命令大全(1)(适合新手)【详细】
- 用js简单绘制杜邦图
- 一个angular版的url中获取参数的插件
- MFC Ultimate Grid
- Android之四大组件、六大布局、五大存储
- 机器学习之自组织特征映射神经网络(SOM)