summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2017-10-30 20:21:27 +0100
committerGitHub <noreply@github.com>2017-10-30 20:21:27 +0100
commit619104b99193e84b561eab8c367a5491c2399450 (patch)
treed701aafa66f03d2ace77c847b52cf3e02e4901bb
parente7aa5af9bea7556fa1f841a08479146ac31a2cc7 (diff)
parent36adac4a165d5205d2545b83f834c2bedd5f3517 (diff)
downloadimag-619104b99193e84b561eab8c367a5491c2399450.zip
imag-619104b99193e84b561eab8c367a5491c2399450.tar.gz
Merge pull request #1136 from matthiasbeyer/imag-diagnostics/init
Imag diagnostics/init
-rw-r--r--Cargo.toml1
-rw-r--r--bin/core/imag-diagnostics/Cargo.toml26
-rw-r--r--bin/core/imag-diagnostics/src/main.rs191
-rw-r--r--bin/core/imag-diagnostics/src/ui.rs25
-rw-r--r--doc/src/09020-changelog.md1
5 files changed, 244 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 3ec4b5b..e927600 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -2,6 +2,7 @@
members = [
"bin/core/imag",
"bin/core/imag-annotate",
+ "bin/core/imag-diagnostics",
"bin/core/imag-gps",
"bin/core/imag-grep",
"bin/core/imag-link",
diff --git a/bin/core/imag-diagnostics/Cargo.toml b/bin/core/imag-diagnostics/Cargo.toml
new file mode 100644
index 0000000..68eafc8
--- /dev/null
+++ b/bin/core/imag-diagnostics/Cargo.toml
@@ -0,0 +1,26 @@
+[package]
+name = "imag-diagnostics"
+version = "0.5.0"
+authors = ["Matthias Beyer <mail@beyermatthias.de>"]
+
+description = "Part of the imag core distribution: imag-gps command"
+
+keywords = ["imag", "PIM", "personal", "information", "management"]
+readme = "../../../README.md"
+license = "LGPL-2.1"
+
+documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.html"
+repository = "https://github.com/matthiasbeyer/imag"
+homepage = "http://imag-pim.org"
+
+[dependencies]
+clap = ">=2.17"
+version = "2.0.1"
+toml = "0.4"
+toml-query = "0.4"
+
+libimagstore = { version = "0.5.0", path = "../../../lib/core/libimagstore" }
+libimagrt = { version = "0.5.0", path = "../../../lib/core/libimagrt" }
+libimagerror = { version = "0.5.0", path = "../../../lib/core/libimagerror" }
+libimagentrylink = { version = "0.5.0", path = "../../../lib/entry/libimagentrylink" }
+
diff --git a/bin/core/imag-diagnostics/src/main.rs b/bin/core/imag-diagnostics/src/main.rs
new file mode 100644
index 0000000..784d98e
--- /dev/null
+++ b/bin/core/imag-diagnostics/src/main.rs
@@ -0,0 +1,191 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+#![deny(
+ non_camel_case_types,
+ non_snake_case,
+ path_statements,
+ trivial_numeric_casts,
+ unstable_features,
+ unused_allocation,
+ unused_import_braces,
+ unused_imports,
+ unused_must_use,
+ unused_mut,
+ unused_qualifications,
+ while_true,
+)]
+
+extern crate clap;
+extern crate toml;
+extern crate toml_query;
+#[macro_use] extern crate version;
+
+extern crate libimagrt;
+extern crate libimagerror;
+extern crate libimagentrylink;
+extern crate libimagstore;
+
+use libimagrt::setup::generate_runtime_setup;
+use libimagerror::trace::MapErrTrace;
+use libimagstore::store::FileLockEntry;
+use libimagstore::storeid::StoreId;
+use libimagstore::iter::get::*;
+use libimagstore::error::StoreError as Error;
+use libimagentrylink::internal::*;
+
+use toml::Value;
+use toml_query::read::TomlValueReadExt;
+
+use std::collections::BTreeMap;
+
+mod ui;
+
+struct Diagnostic {
+ pub id: StoreId,
+ pub entry_store_version: String,
+ pub header_sections: usize,
+ pub bytecount_content: usize,
+ pub overall_byte_size: usize,
+ pub verified: bool,
+ pub num_internal_links: usize,
+}
+
+impl<'a> From<FileLockEntry<'a>> for Diagnostic {
+
+ fn from(entry: FileLockEntry<'a>) -> Diagnostic {
+ Diagnostic {
+ id: entry.get_location().clone(),
+ entry_store_version: entry
+ .get_header()
+ .read("imag.version")
+ .map(|opt| match opt {
+ Some(&Value::String(ref s)) => s.clone(),
+ Some(_) => "Non-String type in 'imag.version'".to_owned(),
+ None => "No version".to_owned(),
+ })
+ .unwrap_or("Error reading version".to_owned()),
+ header_sections: match entry.get_header() {
+ &Value::Table(ref map) => map.keys().count(),
+ _ => 0
+ },
+ bytecount_content: entry.get_content().as_str().len(),
+ overall_byte_size: entry.to_str().as_str().len(),
+ verified: entry.verify().is_ok(),
+ num_internal_links: entry.get_internal_links().map(Iterator::count).unwrap_or(0),
+ }
+ }
+}
+
+fn main() {
+ let rt = generate_runtime_setup("imag-diagnostics",
+ &version!()[..],
+ "Print diagnostics about imag and the imag store",
+ ui::build_ui);
+
+ let diags = rt.store()
+ .entries()
+ .map_err_trace_exit(1)
+ .unwrap()
+ .into_get_iter(rt.store())
+ .map(|e| {
+ e.map_err_trace_exit_unwrap(1)
+ .ok_or(Error::from("Unable to get entry".to_owned()))
+ .map_err_trace_exit_unwrap(1)
+ })
+ .map(Diagnostic::from)
+ .collect::<Vec<_>>();
+
+ let mut version_counts : BTreeMap<String, usize> = BTreeMap::new();
+ let mut sum_header_sections = 0;
+ let mut sum_bytecount_content = 0;
+ let mut sum_overall_byte_size = 0;
+ let mut max_overall_byte_size : Option<(usize, StoreId)> = None;
+ let mut verified_count = 0;
+ let mut unverified_count = 0;
+ let mut num_internal_links = 0;
+ let mut max_internal_links : Option<(usize, StoreId)> = None;
+
+ for diag in diags.iter() {
+ sum_header_sections += diag.header_sections;
+ sum_bytecount_content += diag.bytecount_content;
+ sum_overall_byte_size += diag.overall_byte_size;
+ match max_overall_byte_size {
+ None => max_overall_byte_size = Some((diag.num_internal_links, diag.id.clone())),
+ Some((num, _)) => if num < diag.overall_byte_size {
+ max_overall_byte_size = Some((diag.overall_byte_size, diag.id.clone()));
+ }
+ }
+
+ let n = version_counts.get(&diag.entry_store_version).map(Clone::clone).unwrap_or(0);
+ version_counts.insert(diag.entry_store_version.clone(), n+1);
+
+ if diag.verified {
+ verified_count += 1;
+ } else {
+ unverified_count += 1;
+ }
+
+ num_internal_links += diag.num_internal_links;
+ match max_internal_links {
+ None => max_internal_links = Some((diag.num_internal_links, diag.id.clone())),
+ Some((num, _)) => if num < diag.num_internal_links {
+ max_internal_links = Some((diag.num_internal_links, diag.id.clone()));
+ }
+ }
+ }
+
+ let n = diags.len();
+
+ println!("imag version {}", version!());
+ println!("");
+ println!("{} entries", n);
+ for (k, v) in version_counts {
+ println!("{} entries with store version '{}'", v, k);
+ }
+ if n != 0 {
+ println!("{} header sections in the average entry", sum_header_sections / n);
+ println!("{} average content bytecount", sum_bytecount_content / n);
+ println!("{} average overall bytecount", sum_overall_byte_size / n);
+ if let Some((num, path)) = max_overall_byte_size {
+ println!("Largest Entry ({bytes} bytes): {path}",
+ bytes = num,
+ path = path
+ .into_pathbuf()
+ .map_err_trace_exit_unwrap(1)
+ .to_str()
+ .unwrap_or("Failed converting path to string")
+ );
+ }
+ println!("{} average internal link count per entry", num_internal_links / n);
+ if let Some((num, path)) = max_internal_links {
+ println!("Entry with most internal links ({count}): {path}",
+ count = num,
+ path = path
+ .into_pathbuf()
+ .map_err_trace_exit_unwrap(1)
+ .to_str()
+ .unwrap_or("Failed converting path to string")
+ );
+ }
+ println!("{} verified entries", verified_count);
+ println!("{} unverified entries", unverified_count);
+ }
+}
+
diff --git a/bin/core/imag-diagnostics/src/ui.rs b/bin/core/imag-diagnostics/src/ui.rs
new file mode 100644
index 0000000..c3f2fab
--- /dev/null
+++ b/bin/core/imag-diagnostics/src/ui.rs
@@ -0,0 +1,25 @@
+//
+// imag - the personal information management suite for the commandline
+// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; version
+// 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+use clap::App;
+
+pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
+ app
+}
+
diff --git a/doc/src/09020-changelog.md b/doc/src/09020-changelog.md
index 9129b57..763c476 100644
--- a/doc/src/09020-changelog.md
+++ b/doc/src/09020-changelog.md
@@ -29,6 +29,7 @@ This section contains the changelog from the last release to the next release.
stderr)
* `imag-store` can dump all storeids now
* `imag-annotate` was introduced
+ * `imag-diagnostics` was added
* Minor changes
* `libimagentryannotation` got a rewrite, is not based on `libimagnotes`