go to the qi::log API reference.
Overview
New logs system
New logs goals are to improve and simplify how to use and read them.
Hierarchical Category
There is hierarchical category like in python. for example:
- qi.core.client
- qi.audio.tts
- qi.audio.asr
- ...
This allow easy log filtering. Add improve the readablilty into logs GUI.
Handlers
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::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");
Verbosity
There is now 7 logs levels that you can change using –log-level (-L) [log_level_number] option in order form 0 to 6:
- silent: hide logs.
- fatal: This one is used before exit the program if a fatal error occurred,
- error: classical error,
- warning: useful to warn user,
- info: useful to user informations, logs level by default (also show all lower log level).
- verbose: not mandatory but useful to user informations, not show by default. If you want them you need to use –verbose (-v) option on naoqi command line.
- debug: useful to developer informations. Not compile on release. Show on debug comilaption using –debug (-d) option on naoqi command line.
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
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
Asynchronous log
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. Be careful, 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.
Compat
- allog should continue working.
- allog API should remain identical.
Options
- –log-level (-L) [log_level_number]: change verbosity of logs (0: silent, 1: fatal, 2: error, 3: warning, 4: info, 5: verbose, 6: debug),
- –verbose (-v): show verbose logs level and lower,
- –debug (-d): show debug logs level and lower,
- –quiet (-q): does not show any logs.
- –context (-c): show code location, file(line) function,
- –synchronous-log: make synchronous logs.
Link
qi::log documentation.
Example
#include <boost/program_options.hpp>
namespace po = boost::program_options;
int main(int argc, char **argv)
{
po::options_description desc("Allowed options");
int globalVerbosity;
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), "Change the log minimum level: [0-6] (0: silent, 1: fatal, 2: error, 3: warning, 4: info, 5: verbose, 6: debug). Default: 4 (info)")
;
po::variables_map vm;
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;
}
if (vm.count("log-level"))
{
if (globalVerbosity > 0 && globalVerbosity <= 6)
if (globalVerbosity > 6)
if (globalVerbosity <= 0)
}
if (vm.count("quiet"))
if (vm.count("debug"))
if (vm.count("verbose"))
if (vm.count("context"))
{
int globalContext = vm["context"].as<int>();
if (globalContext < 0)
{
}
else if (globalContext > 7)
{
}
else
{
}
}
if (vm.count("synchronous-log"))
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.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.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;
"Oups my buffer is too bad: %x\n",
0x0BADCAFE);
qiLogError(
"core.log.example.4") <<
"Where is nao?"
<< " - Nao is in the kitchen."
<< " - How many are they? "
<< 42 << std::endl;
qiLogInfo(
"core.log.example.4",
"%d %d ", 41, 42) << 43 <<
" " << 44
<< std::endl;
std::cout << "I've just finished to log!" << std::endl;
}