<commit_before>//! Module providing the TermLogger Implementation

use log::{LogLevel, LogLevelFilter, LogMetadata, LogRecord, SetLoggerError, set_logger, Log};
use time;
use term;
use term::{StderrTerminal, color};
use std::sync::Mutex;
use std::io::Error;
use super::SharedLogger;

/// The TermLogger struct. Provides a stderr based Logger implementation
pub struct TermLogger {
    level: LogLevelFilter,
    stderr: Mutex<Box<StderrTerminal>>,
}

impl TermLogger {

    /// init function. Globally initializes the TermLogger as the one and only used log facility.
    ///
    /// Takes the desired LogLevel as argument. It cannot be changed later on.
    /// Fails if another Logger was already initialized.
    ///
    /// # Examples
    /// '''
    /// let _ = TermLogger::init(LogLevelFilter::Info);
    /// '''
    #[allow(dead_code)]
    pub fn init(log_level: LogLevelFilter) -> Result<(), SetLoggerError> {
        set_logger(|max_log_level| {
            max_log_level.set(log_level.clone());
            TermLogger::new(log_level)
        })
    }

    /// allows to create a new logger, that can be independently used, no matter whats globally set.
    ///
    /// no macros are provided for easy logging in this case and you probably
    /// dont want to use this function, but init().
    ///
    /// Takes the desired LogLevel as argument. It cannot be changed later on.
    ///
    /// # Examples
    /// '''
    /// let term_logger = TermLogger::new(LogLevelFilter::Info);
    /// '''
    #[allow(dead_code)]
    pub fn new(log_level: LogLevelFilter) -> Box<TermLogger> {
        Box::new(TermLogger { level: log_level, stderr: Mutex::new(term::stderr().unwrap()) })
    }

    fn try_log(&self, record: &LogRecord) -> Result<(), Error> {

        if self.enabled(record.metadata()) {
            let mut stderr_lock = self.stderr.lock().unwrap();

            let cur_time = time::now();

            let color = match record.level() {
                LogLevel::Error => color::RED,
                LogLevel::Warn => color::YELLOW,
                LogLevel::Info => color::BLUE,
                LogLevel::Debug => color::CYAN,
                LogLevel::Trace => color::WHITE
            };

            if self.level() <= LogLevel::Warn {
                try!(write!(stderr_lock, "["));
                try!(stderr_lock.fg(color));
                try!(write!(stderr_lock, "{}", record.level()));
                try!(stderr_lock.reset());
                try!(writeln!(stderr_lock,
                    "] {}",
                        record.args()
                ));
            } else {
                try!(write!(stderr_lock, "{:02}:{:02}:{:02} [",
                            cur_time.tm_hour,
                            cur_time.tm_min,
                            cur_time.tm_sec));

                match record.level() {
                    LogLevel::Error |
                    LogLevel::Warn  |
                    LogLevel::Info  |
                    LogLevel::Debug => {
                        try!(stderr_lock.fg(color));
                        try!(write!(stderr_lock, "{}", record.level()));
                        try!(stderr_lock.reset());
                        try!(writeln!(stderr_lock,
                            "] {}: {}",
                                record.target(),
                                record.args()
                        ));
                    },
                    LogLevel::Trace => {
                        try!(writeln!(stderr_lock,
                            "[{}] {}: [{}:{}] - {}",
                                record.level(),
                                record.target(),
                                record.location().file(),<commit_msg>Fix termlog display. TRACE displayed as [[TRACE], not [TRACE].<commit_after>//! Module providing the TermLogger Implementation

use log::{LogLevel, LogLevelFilter, LogMetadata, LogRecord, SetLoggerError, set_logger, Log};
use time;
use term;
use term::{StderrTerminal, color};
use std::sync::Mutex;
use std::io::Error;
use super::SharedLogger;

/// The TermLogger struct. Provides a stderr based Logger implementation
pub struct TermLogger {
    level: LogLevelFilter,
    stderr: Mutex<Box<StderrTerminal>>,
}

impl TermLogger {

    /// init function. Globally initializes the TermLogger as the one and only used log facility.
    ///
    /// Takes the desired LogLevel as argument. It cannot be changed later on.
    /// Fails if another Logger was already initialized.
    ///
    /// # Examples
    /// '''
    /// let _ = TermLogger::init(LogLevelFilter::Info);
    /// '''
    #[allow(dead_code)]
    pub fn init(log_level: LogLevelFilter) -> Result<(), SetLoggerError> {
        set_logger(|max_log_level| {
            max_log_level.set(log_level.clone());
            TermLogger::new(log_level)
        })
    }

    /// allows to create a new logger, that can be independently used, no matter whats globally set.
    ///
    /// no macros are provided for easy logging in this case and you probably
    /// dont want to use this function, but init().
    ///
    /// Takes the desired LogLevel as argument. It cannot be changed later on.
    ///
    /// # Examples
    /// '''
    /// let term_logger = TermLogger::new(LogLevelFilter::Info);
    /// '''
    #[allow(dead_code)]
    pub fn new(log_level: LogLevelFilter) -> Box<TermLogger> {
        Box::new(TermLogger { level: log_level, stderr: Mutex::new(term::stderr().unwrap()) })
    }

    fn try_log(&self, record: &LogRecord) -> Result<(), Error> {

        if self.enabled(record.metadata()) {
            let mut stderr_lock = self.stderr.lock().unwrap();

            let cur_time = time::now();

            let color = match record.level() {
                LogLevel::Error => color::RED,
                LogLevel::Warn => color::YELLOW,
                LogLevel::Info => color::BLUE,
                LogLevel::Debug => color::CYAN,
                LogLevel::Trace => color::WHITE
            };

            if self.level() <= LogLevel::Warn {
                try!(write!(stderr_lock, "["));
                try!(stderr_lock.fg(color));
                try!(write!(stderr_lock, "{}", record.level()));
                try!(stderr_lock.reset());
                try!(writeln!(stderr_lock,
                    "] {}",
                        record.args()
                ));
            } else {
                try!(write!(stderr_lock, "{:02}:{:02}:{:02} [",
                            cur_time.tm_hour,
                            cur_time.tm_min,
                            cur_time.tm_sec));
                try!(stderr_lock.fg(color));
                try!(write!(stderr_lock, "{}", record.level()));
                try!(stderr_lock.reset());
                try!(write!(stderr_lock, "] "));

                match record.level() {
                    LogLevel::Error |
                    LogLevel::Warn  |
                    LogLevel::Info  |
                    LogLevel::Debug => {
                        try!(writeln!(stderr_lock,
                            "{}: {}",
                                record.target(),
                                record.args()
                        ));
                    },
                    LogLevel::Trace => {
                        try!(writeln!(stderr_lock,
                            "{}: [{}:{}] - {}",
                                record.target(),
                                record.location().file(),
{'fraction_non_alphanumeric': 0.1395162368034211, 'fraction_numerical': 0.0016036349057864494, 'mean_word_length': 1.5525238744884038, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2612318', 'n_tokens_mistral': 1998, 'n_tokens_neox': 1918, 'n_words': 447}