From 519f2006e8b33e9b14fdc985766ab4e4e869544b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 5 Jul 2012 14:05:36 +0300 Subject: [PATCH] Better logging system --- source/builder.cpp | 104 ++++++++++++++++++++++------------- source/builder.h | 5 +- source/csourcefile.cpp | 3 +- source/gnucxxcompiler.cpp | 3 +- source/logger.cpp | 21 +++++++ source/logger.h | 19 +++++++ source/package.cpp | 3 +- source/packagemanager.cpp | 9 +-- source/sourcepackage.cpp | 3 +- source/virtualfilesystem.cpp | 6 +- 10 files changed, 118 insertions(+), 58 deletions(-) create mode 100644 source/logger.cpp create mode 100644 source/logger.h diff --git a/source/builder.cpp b/source/builder.cpp index 9548288..1787ec1 100644 --- a/source/builder.cpp +++ b/source/builder.cpp @@ -43,7 +43,6 @@ Builder::Builder(int argc, char **argv): clean(0), dry_run(false), help(false), - verbose(1), show_progress(false), build_file("Build"), jobs(1), @@ -60,6 +59,9 @@ Builder::Builder(int argc, char **argv): string prfx; string arch; bool no_externals = false; + unsigned verbose = 1; + bool silent = false; + list log_channels; GetOpt getopt; getopt.add_option('a', "analyze", analyze_mode, GetOpt::REQUIRED_ARG).set_help("Perform analysis. MODE can be deps, alldeps or rebuild.", "MODE"); @@ -68,7 +70,9 @@ Builder::Builder(int argc, char **argv): getopt.add_option('f', "file", build_file, GetOpt::REQUIRED_ARG).set_help("Read info from FILE instead of Build.", "FILE"); getopt.add_option('h', "help", help, GetOpt::NO_ARG).set_help("Print this message."); getopt.add_option('j', "jobs", jobs, GetOpt::REQUIRED_ARG).set_help("Run NUM commands at once, whenever possible.", "NUM"); + getopt.add_option('l', "log", log_channels, GetOpt::REQUIRED_ARG).set_help("Set log channels to be displayed.", "LIST"); getopt.add_option('n', "dry-run", dry_run, GetOpt::NO_ARG).set_help("Don't actually do anything, only show what would be done."); + getopt.add_option('s', "silent", silent, GetOpt::NO_ARG).set_help("Don't print any messages other than errors."); getopt.add_option('v', "verbose", verbose, GetOpt::NO_ARG).set_help("Print more information about what's going on."); getopt.add_option('x', "no-externals", no_externals, GetOpt::NO_ARG).set_help("Do not load external source packages."); getopt.add_option('A', "conf-all", conf_all, GetOpt::NO_ARG).set_help("Apply configuration to all packages."); @@ -86,6 +90,40 @@ Builder::Builder(int argc, char **argv): helpmsg = getopt.generate_help(); getopt(argc, argv); + if(silent) + --verbose; + if(verbose>=1) + { + logger.enable_channel("summary"); + logger.enable_channel("tasks"); + } + if(verbose>=2) + { + logger.enable_channel("packages"); + logger.enable_channel("commands"); + } + if(verbose>=3) + { + logger.enable_channel("packagemgr"); + logger.enable_channel("configure"); + } + if(verbose>=4) + { + logger.enable_channel("files"); + logger.enable_channel("auxcommands"); + } + if(verbose>=5) + { + logger.enable_channel("tools"); + logger.enable_channel("vfs"); + } + for(list::const_iterator i=log_channels.begin(); i!=log_channels.end(); ++i) + { + vector parts = split(*i, ','); + for(vector::const_iterator j=parts.begin(); j!=parts.end(); ++j) + logger.enable_channel(*j); + } + if(!analyze_mode.empty()) { analyzer = new Analyzer(*this); @@ -233,34 +271,22 @@ int Builder::main() if(create_targets()) return 1; - if(verbose>=2) - { - IO::print("Building on %s, for %s%s\n", native_arch.get_name(), - current_arch->get_name(), (current_arch->is_native() ? " (native)" : "")); - IO::print("Prefix is %s\n", prefix); - } + logger.log("environment", format("Building on %s, for %s%s", native_arch.get_name(), + current_arch->get_name(), (current_arch->is_native() ? " (native)" : ""))); + logger.log("environment", format("Prefix is %s", prefix)); - if(verbose>=1) + const PackageManager::PackageMap &packages = package_manager.get_packages(); + list package_details; + for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) { - const PackageManager::PackageMap &packages = package_manager.get_packages(); - unsigned n_packages = 0; - for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) - if(i->second && i->second->is_configured()) - ++n_packages; - IO::print("%d active packages, %d targets\n", n_packages, targets.size()); - } + if(!i->second || !i->second->is_configured()) + continue; - if(verbose>=2) - { - const PackageManager::PackageMap &packages = package_manager.get_packages(); - for(PackageManager::PackageMap::const_iterator i=packages.begin(); i!=packages.end(); ++i) + string line = i->second->get_name(); + if(dynamic_cast(i->second)) { - if(!i->second->is_configured()) - continue; + line += '*'; - IO::print(" %s", i->second->get_name()); - if(dynamic_cast(i->second)) - IO::print("*"); unsigned count = 0; unsigned to_be_built = 0; for(TargetMap::iterator j=targets.begin(); j!=targets.end(); ++j) @@ -272,15 +298,20 @@ int Builder::main() } if(count) { - IO::print(" (%d targets", count); + line += format(" (%d targets", count); if(to_be_built) - IO::print(", %d to be built", to_be_built); - IO::print(")"); + line += format(", %d to be built", to_be_built); + line += ')'; } - IO::print("\n"); } + + package_details.push_back(line); } + logger.log("summary", format("%d active packages, %d targets", package_details.size(), targets.size())); + for(list::const_iterator i=package_details.begin(); i!=package_details.end(); ++i) + logger.log("packages", *i); + if(analyzer) analyzer->analyze(); @@ -357,8 +388,7 @@ int Builder::load_build_file(const FS::Path &fn) IO::BufferedFile in(fn.str()); - if(verbose>=3) - IO::print("Reading %s\n", fn); + logger.log("files", format("Reading %s", fn)); DataFile::Parser parser(in, fn.str()); Loader loader(*this, fn.subpath(0, fn.size()-1)); @@ -442,11 +472,10 @@ int Builder::do_build() if(!total) { - IO::print("Already up to date\n"); + logger.log("summary", "Already up to date"); return 0; } - if(verbose>=1) - IO::print("Will build %d target%s\n", total, (total!=1 ? "s" : "")); + logger.log("summary", format("Will build %d target%s", total, (total!=1 ? "s" : ""))); vector tasks; @@ -463,12 +492,11 @@ int Builder::do_build() if(tgt) { if(tgt->get_tool()) - IO::print("%-4s %s\n", tgt->get_tool()->get_tag(), tgt->get_name()); + logger.log("tasks", format("%-4s %s", tgt->get_tool()->get_tag(), tgt->get_name())); Task *task = tgt->build(); if(task) { - if(verbose>=2) - IO::print("%s\n", task->get_command()); + logger.log("commands", format("%s", task->get_command())); if(dry_run) { task->signal_finished.emit(true); @@ -512,9 +540,9 @@ int Builder::do_build() if(show_progress) IO::print("\033[K"); if(fail) - IO::print("Build failed\n"); + logger.log("summary", "Build failed"); else if(show_progress) - IO::print("Build complete\n"); + logger.log("summary", "Build complete"); return fail; } diff --git a/source/builder.h b/source/builder.h index 0dc16d1..78244e8 100644 --- a/source/builder.h +++ b/source/builder.h @@ -9,6 +9,7 @@ #include #include "architecture.h" #include "config.h" +#include "logger.h" #include "misc.h" #include "packagemanager.h" #include "problem.h" @@ -77,6 +78,7 @@ private: ProfileTemplateMap profile_tmpl; Toolchain toolchain; VirtualFileSystem vfs; + Logger logger; ProblemList problems; Analyzer *analyzer; @@ -84,7 +86,6 @@ private: unsigned clean; bool dry_run; bool help; - unsigned verbose; bool show_progress; std::string build_file; unsigned jobs; @@ -104,7 +105,6 @@ public: ~Builder(); int main(); - unsigned get_verbose() const { return verbose; } bool get_dry_run() const { return dry_run; } PackageManager &get_package_manager() { return package_manager; } @@ -124,6 +124,7 @@ public: const Toolchain &get_toolchain() const { return toolchain; } VirtualFileSystem &get_vfs() { return vfs; } + const Logger &get_logger() const { return logger; } /** Adds a target to both the target map and the new target queue. Called from Target constructor. */ diff --git a/source/csourcefile.cpp b/source/csourcefile.cpp index dee807b..d3cb807 100644 --- a/source/csourcefile.cpp +++ b/source/csourcefile.cpp @@ -37,8 +37,7 @@ void CSourceFile::find_depends() { IO::BufferedFile in(path.str()); - if(builder.get_verbose()>=4) - IO::print("Reading includes from %s\n", path.str()); + builder.get_logger().log("files", format("Reading includes from %s", path.str())); Regex r_include("^[ \t]*#include[ \t]+([\"<].*)[\">]"); diff --git a/source/gnucxxcompiler.cpp b/source/gnucxxcompiler.cpp index 0923581..3e0a4b8 100644 --- a/source/gnucxxcompiler.cpp +++ b/source/gnucxxcompiler.cpp @@ -34,8 +34,7 @@ GnuCxxCompiler::GnuCxxCompiler(Builder &b): FS::Path cxx_path = FS::Path("/usr/include/c++")/cxx_ver; if(FS::is_dir(cxx_path)) { - if(builder.get_verbose()>=5) - IO::print("%s version is %s\n", name, cxx_ver); + builder.get_logger().log("tools", format("%s version is %s", name, cxx_ver)); system_path.push_back(cxx_path); break; } diff --git a/source/logger.cpp b/source/logger.cpp new file mode 100644 index 0000000..901800e --- /dev/null +++ b/source/logger.cpp @@ -0,0 +1,21 @@ +#include +#include "logger.h" + +using namespace std; +using namespace Msp; + +void Logger::enable_channel(const string &chan) +{ + enabled_channels.insert(chan); +} + +void Logger::disable_channel(const string &chan) +{ + enabled_channels.erase(chan); +} + +void Logger::log(const string &chan, const string &message) const +{ + if(enabled_channels.count(chan)) + IO::print("%s\n", message); +} diff --git a/source/logger.h b/source/logger.h new file mode 100644 index 0000000..c22339f --- /dev/null +++ b/source/logger.h @@ -0,0 +1,19 @@ +#ifndef LOGGER_H_ +#define LOGGER_H_ + +#include +#include + +class Logger +{ +private: + std::set enabled_channels; + +public: + void enable_channel(const std::string &); + void disable_channel(const std::string &); + + void log(const std::string &, const std::string &) const; +}; + +#endif diff --git a/source/package.cpp b/source/package.cpp index 8a05ddc..38829f7 100644 --- a/source/package.cpp +++ b/source/package.cpp @@ -22,8 +22,7 @@ void Package::configure(const StringMap &opts, unsigned flag) if(conf_done) return; - if(builder.get_verbose()>=3) - IO::print("Configuring %s\n", name); + builder.get_logger().log("configure", format("Configuring %s", name)); do_configure(opts, flag); diff --git a/source/packagemanager.cpp b/source/packagemanager.cpp index c3d6939..6818920 100644 --- a/source/packagemanager.cpp +++ b/source/packagemanager.cpp @@ -100,8 +100,7 @@ string PackageManager::run_pkgconfig(const string &pkg, const string &what) argv.push_back("--variable="+what); argv.push_back(pkg); - if(builder.get_verbose()>=4) - IO::print("Running %s\n", join(argv.begin(), argv.end())); + builder.get_logger().log("auxcommands", format("Running %s", join(argv.begin(), argv.end()))); ExternalTask task(argv); task.set_stdout(ExternalTask::CAPTURE); @@ -118,8 +117,7 @@ string PackageManager::run_pkgconfig(const string &pkg, const string &what) FS::Path PackageManager::get_package_location(const string &name) { - if(builder.get_verbose()>=3) - IO::print("Looking for package %s\n", name); + builder.get_logger().log("packagemgr", format("Looking for package %s", name)); try { @@ -143,8 +141,7 @@ FS::Path PackageManager::get_package_location(const string &name) pkg_dirs.push_back(full); } } - if(builder.get_verbose()>=3) - IO::print("%d packages found in path\n", pkg_dirs.size()); + builder.get_logger().log("packagemgr", format("%d packages found in path", pkg_dirs.size())); } bool msp = !name.compare(0, 3, "msp"); diff --git a/source/sourcepackage.cpp b/source/sourcepackage.cpp index d66a36f..ab66c00 100644 --- a/source/sourcepackage.cpp +++ b/source/sourcepackage.cpp @@ -130,8 +130,7 @@ void SourcePackage::do_configure(const StringMap &opts, unsigned flag) if(flag && config.update(opts)) { - if(builder.get_verbose()>=2) - IO::print("Configuration of %s changed\n", name); + builder.get_logger().log("configure", format("Configuration of %s changed", name)); if(!builder.get_dry_run()) config.save(); } diff --git a/source/virtualfilesystem.cpp b/source/virtualfilesystem.cpp index 0ada219..b5e16d4 100644 --- a/source/virtualfilesystem.cpp +++ b/source/virtualfilesystem.cpp @@ -53,8 +53,7 @@ FileTarget *VirtualFileSystem::find_header(const string &name, const SearchPath if(i!=include_cache.end()) return i->second; - if(builder.get_verbose()>=5) - IO::print("Looking for header %s with path %s\n", name, join(path.begin(), path.end())); + builder.get_logger().log("vfs", format("Looking for header %s with path %s", name, join(path.begin(), path.end()))); // XXX This will cause trouble with multiple architectures in a single build const Tool *tool = builder.get_toolchain().get_tool_for_suffix(FS::extpart(FS::basename(name)), true); @@ -87,8 +86,7 @@ FileTarget *VirtualFileSystem::find_library(const string &lib, const SearchPath const Tool &linker = builder.get_toolchain().get_tool("LINK"); const Tool::SearchPath &syspath = linker.get_system_path(); - if(builder.get_verbose()>=5) - IO::print("Looking for library %s with path %s\n", lib, join(path.begin(), path.end())); + builder.get_logger().log("vfs", format("Looking for library %s with path %s", lib, join(path.begin(), path.end()))); FileTarget *tgt = 0; for(SearchPath::const_iterator j=path.begin(); (!tgt && j!=path.end()); ++j) -- 2.45.2