~matthiasbeyer/imag

4b9ffb498e243c843af32c1f3fa8b05069525c5e — Matthias Beyer 1 year, 1 month ago 1af3cd4 + 675820b
Merge branch 'logger/remove-modules' into master

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
3 files changed, 18 insertions(+), 280 deletions(-)

M imagrc.toml
M lib/core/libimagrt/src/lib.rs
M lib/core/libimagrt/src/logger.rs
M imagrc.toml => imagrc.toml +0 -140
@@ 94,146 94,6 @@ warn  = "[imag][{{bold level}}]: {{yellow message}}"
error = "[imag][{{red level}}]: {{red message}}"

#
# The logging configurations for the modules of imag follow.
#
# Note that the `destinations` key is for _additional_ destinations to the
# default destination in `imag.logging.destinations`, not as replacement! So
# specifying stderr (`-`) in `imag.logging.destinations` _and_ in, for example,
# `imag.logging.modules.libimagstore` yields each log line twice, which might
# not be wanted behaviour.
#

[imag.logging.modules.libimagutil]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagtimeui]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimaginteraction]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagstore]
destinations = [ "/tmp/libimagstore.log" ]
level = "trace"
enabled = true

[imag.logging.modules.libimagrt]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagerror]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagbookmark]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimaghabit]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagnotes]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagcontact]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagdiary]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagtimetrack]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimaglog]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagtodo]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagmail]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentryfilter]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentrycategory]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentryannotation]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentrylink]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentrytag]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentrygps]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentryedit]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentryref]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentryview]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentrymarkdown]
destinations = []
level = "debug"
enabled = true

[imag.logging.modules.libimagentryutil]
destinations = []
level = "debug"
enabled = true

#
# Configuration options for the user interface
#
[ui]

M lib/core/libimagrt/src/lib.rs => lib/core/libimagrt/src/lib.rs +0 -1
@@ 42,7 42,6 @@ extern crate itertools;
extern crate ansi_term;
extern crate handlebars;
extern crate serde;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate failure;
#[macro_use] extern crate toml_query;


M lib/core/libimagrt/src/logger.rs => lib/core/libimagrt/src/logger.rs +18 -139
@@ 37,8 37,6 @@ use handlebars::Handlebars;

use libimagerror::errors::ErrorMsg as EM;

type ModuleName = String;

#[derive(Debug)]
enum LogDestination {
    Stderr,


@@ 51,15 49,6 @@ impl Default for LogDestination {
    }
}

#[derive(Debug)]
struct ModuleSettings {
    enabled:        bool,
    level:          Option<Level>,

    #[allow(unused)]
    destinations:   Option<Vec<LogDestination>>,
}

/// Logger implementation for `log` crate.
#[derive(Debug)]
pub struct ImagLogger {


@@ 67,12 56,6 @@ pub struct ImagLogger {

    #[allow(unused)]
    global_destinations : Vec<LogDestination>,
    // global_format_trace : ,
    // global_format_debug : ,
    // global_format_info  : ,
    // global_format_warn  : ,
    // global_format_error : ,
    module_settings     : BTreeMap<ModuleName, ModuleSettings>,

    handlebars: Handlebars,
}


@@ 100,7 83,6 @@ impl ImagLogger {
        Ok(ImagLogger {
            global_loglevel     : aggregate_global_loglevel(matches, config)?,
            global_destinations : aggregate_global_destinations(config)?,
            module_settings     : aggregate_module_settings(matches, config)?,
            handlebars,
        })
    }


@@ 153,45 135,13 @@ impl Log for ImagLogger {
            }
        };

        // hack to get the right target configuration.
        // If there is no element here, we use the empty string which automatically drops through
        // to the unwrap_or_else() case
        let record_target = record
            .target()
            .split("::")
            .next()
            .unwrap_or("");

        self.module_settings
            .get(record_target)
            .map(|module_setting| {
                let set = module_setting.enabled &&
                    (module_setting.level.unwrap_or(self.global_loglevel) >= record.level()
                     || self.global_loglevel >= record.level());

                if set {
                    if let Some(destinations) = &module_setting.destinations {
                        for d in destinations {
                            // If there's an error, we cannot do anything, can we?
                            log_to_destination(&d);
                        }
                    }

                    for d in self.global_destinations.iter() {
                        // If there's an error, we cannot do anything, can we?
                        log_to_destination(&d);
                    }
                }
            })
        .unwrap_or_else(|| {
            if self.global_loglevel >= record.level() {
                // Yes, we log
                for d in self.global_destinations.iter() {
                    // If there's an error, we cannot do anything, can we?
                    log_to_destination(&d);
                }
        if self.global_loglevel >= record.level() {
            // Yes, we log
            for d in self.global_destinations.iter() {
                // If there's an error, we cannot do anything, can we?
                log_to_destination(&d);
            }
        });
        }
    }
}



@@ 264,22 214,7 @@ fn translate_destination(raw: &str) -> Result<LogDestination> {
    }
}


fn translate_destinations(raw: &[Value]) -> Result<Vec<LogDestination>> {
    raw.iter()
        .map(|val| {
            val.as_str()
                .ok_or_else(|| "Type error at 'imag.logging.modules.<mod>.destinations', expected Array<String>")
                .map_err(err_msg)
                .map_err(Error::from)
                .and_then(|s| translate_destination(s))
        })
        .collect()
}

fn aggregate_global_destinations(config: Option<&Value>)
    -> Result<Vec<LogDestination>>
{
fn aggregate_global_destinations(config: Option<&Value>) -> Result<Vec<LogDestination>> {
    match config {
        None      => Ok(vec![LogDestination::default()]),
        Some(cfg) => cfg


@@ 292,7 227,17 @@ fn aggregate_global_destinations(config: Option<&Value>)
                let msg = "Type error at 'imag.logging.destinations', expected 'Array'";
                err_msg(msg)
            })
            .and_then(|val| translate_destinations(val)),
            .and_then(|raw| {
                raw.iter()
                    .map(|val| {
                        val.as_str()
                            .ok_or_else(|| "Type error at 'imag.logging.modules.<mod>.destinations', expected Array<String>")
                            .map_err(err_msg)
                            .map_err(Error::from)
                            .and_then(|s| translate_destination(s))
                    })
                    .collect::<Result<Vec<LogDestination>>>()
            }),
    }
}



@@ 347,69 292,3 @@ mod log_lvl_aggregate {

}

fn aggregate_module_settings(_matches: &ArgMatches, config: Option<&Value>)
    -> Result<BTreeMap<ModuleName, ModuleSettings>>
{
    use std::convert::TryInto;

    //
    // We define helper types here for deserializing easily using typed toml-query functionality.
    //
    // We need the helper types because we cannot deserialize in the target types directly, because
    // of the `File(Arc<Mutex<::std::fs::File>>)` variant in `LogDestination`, which would
    // technically possible to deserialize the toml into the type, but it might be a bad idea.
    //
    // This code is idomatic enough for the conversions, so it is not a big painpoint.
    //

    #[derive(Serialize, Deserialize, Debug)]
    struct LoggingModuleConfig {
        pub destinations: Option<Vec<String>>,
        pub level: Option<Level>,
        pub enabled: bool,
    }

    #[derive(Partial, Serialize, Deserialize, Debug)]
    #[location = "imag.logging.modules"]
    struct LoggingModuleConfigMap(BTreeMap<String, LoggingModuleConfig>);

    impl TryInto<BTreeMap<String, ModuleSettings>> for LoggingModuleConfigMap {
        type Error = Error;

        fn try_into(self) -> Result<BTreeMap<String, ModuleSettings>> {
            let mut map = BTreeMap::new();

            for (key, value) in self.0.into_iter() {
                map.insert(key, ModuleSettings {
                    enabled:      value.enabled,
                    level:        value.level.map(Into::into),
                    destinations: match value.destinations {
                        None     => None,
                        Some(ds) => Some(ds
                            .iter()
                            .map(Deref::deref)
                            .map(translate_destination) // This is why we do this whole thing
                            .collect::<Result<Vec<LogDestination>>>()?)
                    },
                });
            }

            Ok(map)
        }
    }

    match config {
        Some(cfg) => cfg.read_partial::<LoggingModuleConfigMap>()?
            .ok_or_else(|| err_msg("Logging configuration missing"))?
            .try_into()
            .map_err(Error::from),
        None => {
            write!(stderr(), "No Configuration.").ok();
            write!(stderr(), "cannot find module-settings for logging.").ok();
            write!(stderr(), "Will use global defaults").ok();

            Ok(BTreeMap::new())
        }
    }
}