libqi
1.14.5
|
go to the qi::log API reference.
New logs goals are to improve and simplify how to use and read them.
There is hierarchical category like in python. for example:
This allow easy log filtering. Add improve the readablilty into logs GUI.
The default handler log to console. The color is enable on tty. The handler can be added or deleted. You just need to give a delegate to a log function with the following prototype:
void logfct(const qi::log::LogLevel verb, const char *category, const char *msg, const char *file = "", const char *fct = "", const int line = 0);
Then you can add the handler with addLogHandler(name, fctLog)
addLogHandler("nameofloghandler", logfct);
and remove it with removeLogHandler(name).
addLogHandler("nameofloghandler");
There is now 7 logs levels that you can change using --log-level (-L) [log_level_number] option in order form 0 to 6:
Example printing only error and lower log levels:
$ ./a.out -L 2
Output:
I've just finished to log! [FATAL] ...log.example.1: 41 [ERROR] ...log.example.1: 42 [FATAL] ...log.example.2: f4 [ERROR] ...log.example.2: e4 [FATAL] ...log.example.3: 21f4 [ERROR] ...log.example.3: 21e4 [ERROR] ...log.example.4: Where is nao? - Nao is in the kitchen. - How many are they? 42
Code location is supported. You can get some information where is the logs call:
This is an option. You can get the location using --context (-c) on noaqi command line.
Example printing context logs:
$ ./a.out -c
Output:
I've just finished to log! [FATAL] ...log.example.1: log_example.cpp(91) main 41 [ERROR] ...log.example.1: log_example.cpp(92) main 42 [WARN ] ...log.example.1: log_example.cpp(93) main 43 [INFO ] ...log.example.1: log_example.cpp(94) main 44 [FATAL] ...log.example.2: log_example.cpp(98) main f4 [ERROR] ...log.example.2: log_example.cpp(99) main e4 [WARN ] ...log.example.2: log_example.cpp(100) main w4 [INFO ] ...log.example.2: log_example.cpp(101) main i4 [FATAL] ...log.example.3: log_example.cpp(105) main 21f4 [ERROR] ...log.example.3: log_example.cpp(106) main 21e4 [WARN ] ...log.example.3: log_example.cpp(107) main 21w4 [INFO ] ...log.example.3: log_example.cpp(108) main 21i4 [WARN ] ...log.example.4: log_example.cpp(115) main Oups my buffer is too bad: badcafe [ERROR] ...log.example.4: log_example.cpp(118) main Where is nao? - Nao is in the kitchen. - How many are they? 42 [INFO ] ...log.example.4: log_example.cpp(124) main 41 42 43 44
Log are asynchronous, we dont want to waste time in log, furthermore log can do networking. The handling of the log output is in a separated thread.
There is a way to disable asynchronous. Start naoqi with --synchronous-log command line option. Becarefull, it will slow down naoqi if you have lots of handlers.
Logs may be asynchronous, but they are actually being displayed in their request order.
Example printing synchronous logs:
$ ./a.out --synchronous-log
Output:
[FATAL] ...log.example.1: 41 [ERROR] ...log.example.1: 42 [WARN ] ...log.example.1: 43 [INFO ] ...log.example.1: 44 [FATAL] ...log.example.2: f4 [ERROR] ...log.example.2: e4 [WARN ] ...log.example.2: w4 [INFO ] ...log.example.2: i4 [FATAL] ...log.example.3: 21f4 [ERROR] ...log.example.3: 21e4 [WARN ] ...log.example.3: 21w4 [INFO ] ...log.example.3: 21i4 [WARN ] ...log.example.4: Oups my buffer is too bad: badcafe [ERROR] ...log.example.4: Where is nao? - Nao is in the kitchen. - How many are they? 42 [INFO ] ...log.example.4: 41 42 43 44 I've just finished to log!
"I've just finished to log!" is print after everything else.
qi::log documentation.
/* * Copyright (c) 2012 Aldebaran Robotics. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the COPYING file. */ #include <qi/log.hpp> #include <boost/program_options.hpp> namespace po = boost::program_options; int main(int argc, char **argv) { po::options_description desc("Allowed options"); int globalVerbosity; // Used to parse options, as well as to put help message desc.add_options() ("help,h", "Produces help message") ("version", "Output NAOqi version.") ("verbose,v", "Set verbose verbosity.") ("debug,d", "Set debug verbosity.") ("quiet,q", "Do not show logs on console.") ("context,c", po::value<int>(), "Show context logs: [0-7] (0: none, 1: categories, 2: date, 3: file+line, 4: date+categories, 5: date+line+file, 6: categories+line+file, 7: all (date+categories+line+file+function)).") ("synchronous-log", "Activate synchronous logs.") ("log-level,L", po::value<int>(&globalVerbosity)->default_value(4), "Change the log minimum level: [0-6] (0: silent, 1: fatal, 2: error, 3: warning, 4: info, 5: verbose, 6: debug). Default: 4 (info)") ; // Map containing all the options with their values po::variables_map vm; // program option library throws all kind of errors, we just catch them // all, print usage and exit try { po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); } catch (po::error &e) { std::cerr << e.what() << std::endl; std::cout << desc << std::endl; exit(1); } if (vm.count("help")) { std::cout << desc << std::endl; return 0; } // set default log verbosity qi::log::setVerbosity(qi::log::info); // set default log context qi::log::setContext(0); if (vm.count("log-level")) { if (globalVerbosity > 0 && globalVerbosity <= 6) qi::log::setVerbosity((qi::log::LogLevel)globalVerbosity); if (globalVerbosity > 6) qi::log::setVerbosity(qi::log::debug); if (globalVerbosity <= 0) qi::log::setVerbosity(qi::log::silent); } // Remove consoleloghandler (default log handler) if (vm.count("quiet")) qi::log::removeLogHandler("consoleloghandler"); if (vm.count("debug")) qi::log::setVerbosity(qi::log::debug); if (vm.count("verbose")) qi::log::setVerbosity(qi::log::verbose); if (vm.count("context")) { int globalContext = vm["context"].as<int>(); if (globalContext < 0) { qi::log::setContext(0); } else if (globalContext > 7) { qi::log::setContext(7); } else { qi::log::setContext(globalContext); } } if (vm.count("synchronous-log")) qi::log::setSynchronousLog(true); qiLogFatal("core.log.example.1", "%d\n", 41); qiLogError("core.log.example.1", "%d\n", 42); qiLogWarning("core.log.example.1", "%d\n", 43); qiLogInfo("core.log.example.1", "%d\n", 44); qiLogVerbose("core.log.example.1", "%d\n", 45); qiLogDebug("core.log.example.1", "%d\n", 46); qiLogFatal("core.log.example.2") << "f" << 4 << std::endl; qiLogError("core.log.example.2") << "e" << 4 << std::endl; qiLogWarning("core.log.example.2") << "w" << 4 << std::endl; qiLogInfo("core.log.example.2") << "i" << 4 << std::endl; qiLogVerbose("core.log.example.2") << "v" << 4 << std::endl; qiLogDebug("core.log.example.2") << "d" << 4 << std::endl; qiLogFatal("core.log.example.1", "without '\\n': %d", 41); qiLogError("core.log.example.1", "without '\\n': %d", 42); qiLogWarning("core.log.example.1", "without '\\n': %d", 43); qiLogInfo("core.log.example.1", "without '\\n': %d", 44); qiLogVerbose("core.log.example.1", "without '\\n': %d", 45); qiLogDebug("core.log.example.1", "without '\\n': %d", 46); qiLogFatal("core.log.example.1", ""); qiLogFatal("core.log.example.1", "\n"); qiLogFatal("core.log.example.2") << "f " << "without '\\n'"; qiLogError("core.log.example.2") << "e " << "without '\\n'"; qiLogWarning("core.log.example.2") << "w " << "without '\\n'"; qiLogInfo("core.log.example.2") << "i " << "without '\\n'"; qiLogVerbose("core.log.example.2") << "v " << "without '\\n'"; qiLogDebug("core.log.example.2") << "d " << "without '\\n'"; qiLogFatal("core.log.example.2") << ""; qiLogFatal("core.log.example.2") << std::endl; qiLogFatal("core.log.example.3", "%d", 21) << "f" << 4 << std::endl; qiLogError("core.log.example.3", "%d", 21) << "e" << 4 << std::endl; qiLogWarning("core.log.example.3", "%d", 21) << "w" << 4 << std::endl; qiLogInfo("core.log.example.3", "%d", 21) << "i" << 4 << std::endl; qiLogVerbose("core.log.example.3", "%d", 21) << "v" << 4 << std::endl; qiLogDebug("core.log.example.3", "%d", 21) << "d" << 4 << std::endl; //c style qiLogWarning("core.log.example.4", "Oups my buffer is too bad: %x\n", 0x0BADCAFE); //c++ style qiLogError("core.log.example.4") << "Where is nao?" << " - Nao is in the kitchen." << " - How many are they? " << 42 << std::endl; //mixup style qiLogInfo("core.log.example.4", "%d %d ", 41, 42) << 43 << " " << 44 << std::endl; std::cout << "I've just finished to log!" << std::endl; }