Commit 7fedf106f23ce38d6eaaab290939476a86cd4b42
1 parent
83979846
add logging capabilities
Showing
2 changed files
with
211 additions
and
11 deletions
include/GApplication.hpp
| @@ -55,21 +55,35 @@ public: | @@ -55,21 +55,35 @@ public: | ||
| 55 | std::string version(void) const; | 55 | std::string version(void) const; |
| 56 | double telapse(void) const; | 56 | double telapse(void) const; |
| 57 | GPar* par(const std::string& name); | 57 | GPar* par(const std::string& name); |
| 58 | + bool logTerse(void) const; | ||
| 59 | + bool logNormal(void) const; | ||
| 60 | + bool logExplicit(void) const; | ||
| 61 | + bool logVerbose(void) const; | ||
| 62 | + bool logDebug(void) const; | ||
| 58 | 63 | ||
| 64 | + // Public members | ||
| 65 | + GLog log; //!< Application logger | ||
| 66 | + | ||
| 59 | protected: | 67 | protected: |
| 60 | // Protected methods | 68 | // Protected methods |
| 61 | void init_members(void); | 69 | void init_members(void); |
| 62 | void copy_members(const GApplication& app); | 70 | void copy_members(const GApplication& app); |
| 63 | void free_members(void); | 71 | void free_members(void); |
| 64 | - std::string parfilename(void) const; | 72 | + std::string par_filename(void) const; |
| 73 | + std::string log_filename(void) const; | ||
| 74 | + void get_par_standard(void); | ||
| 75 | + void log_header(void); | ||
| 76 | + void log_trailer(void); | ||
| 65 | 77 | ||
| 66 | // Protected data members | 78 | // Protected data members |
| 67 | std::string m_name; //!< Application name | 79 | std::string m_name; //!< Application name |
| 68 | std::string m_version; //!< Application version | 80 | std::string m_version; //!< Application version |
| 69 | std::vector<std::string> m_args; //!< Command line arguments | 81 | std::vector<std::string> m_args; //!< Command line arguments |
| 70 | time_t m_tstart; //!< Start time of execution | 82 | time_t m_tstart; //!< Start time of execution |
| 71 | - GLog m_logger; //!< Application logger | ||
| 72 | GPars m_pars; //!< Application parameters | 83 | GPars m_pars; //!< Application parameters |
| 84 | + int m_chatter; //!< Chatter level | ||
| 85 | + bool m_clobber; //!< Clobber flag | ||
| 86 | + bool m_debug; //!< Debugging mode activated | ||
| 73 | }; | 87 | }; |
| 74 | 88 | ||
| 75 | #endif /* GAPPLICATION_HPP */ | 89 | #endif /* GAPPLICATION_HPP */ |
src/app/GApplication.cpp
| @@ -30,6 +30,7 @@ | @@ -30,6 +30,7 @@ | ||
| 30 | /* __ Macros _____________________________________________________________ */ | 30 | /* __ Macros _____________________________________________________________ */ |
| 31 | 31 | ||
| 32 | /* __ Coding definitions _________________________________________________ */ | 32 | /* __ Coding definitions _________________________________________________ */ |
| 33 | +const int header_width = 80; //!< Header width | ||
| 33 | 34 | ||
| 34 | /* __ Debug definitions __________________________________________________ */ | 35 | /* __ Debug definitions __________________________________________________ */ |
| 35 | 36 | ||
| @@ -74,8 +75,14 @@ GApplication::GApplication(const std::string& name, const std::string& version) | @@ -74,8 +75,14 @@ GApplication::GApplication(const std::string& name, const std::string& version) | ||
| 74 | // Save the execution start time | 75 | // Save the execution start time |
| 75 | time(&m_tstart); | 76 | time(&m_tstart); |
| 76 | 77 | ||
| 78 | + // Initialise the application logger | ||
| 79 | + log.open(log_filename(), true); | ||
| 80 | + | ||
| 77 | // Initialise application parameters | 81 | // Initialise application parameters |
| 78 | - m_pars.load(parfilename()); | 82 | + m_pars.load(par_filename()); |
| 83 | + | ||
| 84 | + // Get standard parameters from parameter file | ||
| 85 | + get_par_standard(); | ||
| 79 | 86 | ||
| 80 | // Return | 87 | // Return |
| 81 | return; | 88 | return; |
| @@ -103,12 +110,18 @@ GApplication::GApplication(const std::string& name, const std::string& version, | @@ -103,12 +110,18 @@ GApplication::GApplication(const std::string& name, const std::string& version, | ||
| 103 | // Save the execution start time | 110 | // Save the execution start time |
| 104 | time(&m_tstart); | 111 | time(&m_tstart); |
| 105 | 112 | ||
| 113 | + // Initialise the application logger | ||
| 114 | + log.open(log_filename(), true); | ||
| 115 | + | ||
| 106 | // Save arguments as vector of strings | 116 | // Save arguments as vector of strings |
| 107 | for (int i = 0; i < argc; ++i) | 117 | for (int i = 0; i < argc; ++i) |
| 108 | m_args.push_back(strip_whitespace(argv[i])); | 118 | m_args.push_back(strip_whitespace(argv[i])); |
| 109 | 119 | ||
| 110 | // Initialise application parameters | 120 | // Initialise application parameters |
| 111 | - m_pars.load(parfilename(), m_args); | 121 | + m_pars.load(par_filename(), m_args); |
| 122 | + | ||
| 123 | + // Get standard parameters from parameter file | ||
| 124 | + get_par_standard(); | ||
| 112 | 125 | ||
| 113 | // Return | 126 | // Return |
| 114 | return; | 127 | return; |
| @@ -138,9 +151,6 @@ GApplication::GApplication(const GApplication& app) | @@ -138,9 +151,6 @@ GApplication::GApplication(const GApplication& app) | ||
| 138 | ***************************************************************************/ | 151 | ***************************************************************************/ |
| 139 | GApplication::~GApplication(void) | 152 | GApplication::~GApplication(void) |
| 140 | { | 153 | { |
| 141 | - // Save application parameters | ||
| 142 | - m_pars.save(parfilename()); | ||
| 143 | - | ||
| 144 | // Free members | 154 | // Free members |
| 145 | free_members(); | 155 | free_members(); |
| 146 | 156 | ||
| @@ -248,6 +258,69 @@ GPar* GApplication::par(const std::string& name) | @@ -248,6 +258,69 @@ GPar* GApplication::par(const std::string& name) | ||
| 248 | } | 258 | } |
| 249 | 259 | ||
| 250 | 260 | ||
| 261 | +/***********************************************************************//** | ||
| 262 | + * @brief Signal terse logging | ||
| 263 | + * | ||
| 264 | + * The terse level is used for the most crucial application information that | ||
| 265 | + * should be logged in all cases (chatter >= 1). | ||
| 266 | + ***************************************************************************/ | ||
| 267 | +bool GApplication::logTerse(void) const | ||
| 268 | +{ | ||
| 269 | + // Return terse logging condition | ||
| 270 | + return (m_chatter > 0); | ||
| 271 | +} | ||
| 272 | + | ||
| 273 | + | ||
| 274 | +/***********************************************************************//** | ||
| 275 | + * @brief Signal normal logging | ||
| 276 | + * | ||
| 277 | + * The normal level is used for standard application information that should | ||
| 278 | + * be logged in normal operations (chatter >= 2). | ||
| 279 | + ***************************************************************************/ | ||
| 280 | +bool GApplication::logNormal(void) const | ||
| 281 | +{ | ||
| 282 | + // Return normal logging condition | ||
| 283 | + return (m_chatter > 1); | ||
| 284 | +} | ||
| 285 | + | ||
| 286 | + | ||
| 287 | +/***********************************************************************//** | ||
| 288 | + * @brief Signal explicit logging | ||
| 289 | + * | ||
| 290 | + * The explicit level is used for detailed application information that | ||
| 291 | + * should be logged in detailed studies (chatter >= 3). | ||
| 292 | + ***************************************************************************/ | ||
| 293 | +bool GApplication::logExplicit(void) const | ||
| 294 | +{ | ||
| 295 | + // Return explicit logging condition | ||
| 296 | + return (m_chatter > 2); | ||
| 297 | +} | ||
| 298 | + | ||
| 299 | + | ||
| 300 | +/***********************************************************************//** | ||
| 301 | + * @brief Signal verbose logging | ||
| 302 | + * | ||
| 303 | + * The verbose level is used for full application information (chatter >= 4). | ||
| 304 | + ***************************************************************************/ | ||
| 305 | +bool GApplication::logVerbose(void) const | ||
| 306 | +{ | ||
| 307 | + // Return verbose logging condition | ||
| 308 | + return (m_chatter > 3); | ||
| 309 | +} | ||
| 310 | + | ||
| 311 | + | ||
| 312 | +/***********************************************************************//** | ||
| 313 | + * @brief Signal debug logging | ||
| 314 | + * | ||
| 315 | + * The debug level is used for application debugging. | ||
| 316 | + ***************************************************************************/ | ||
| 317 | +bool GApplication::logDebug(void) const | ||
| 318 | +{ | ||
| 319 | + // Return debug condition | ||
| 320 | + return (m_debug); | ||
| 321 | +} | ||
| 322 | + | ||
| 323 | + | ||
| 251 | /*========================================================================== | 324 | /*========================================================================== |
| 252 | = = | 325 | = = |
| 253 | = Private methods = | 326 | = Private methods = |
| @@ -259,11 +332,18 @@ GPar* GApplication::par(const std::string& name) | @@ -259,11 +332,18 @@ GPar* GApplication::par(const std::string& name) | ||
| 259 | ***************************************************************************/ | 332 | ***************************************************************************/ |
| 260 | void GApplication::init_members(void) | 333 | void GApplication::init_members(void) |
| 261 | { | 334 | { |
| 262 | - // Initialise members | 335 | + // Initialise public members |
| 336 | + log.clear(); | ||
| 337 | + | ||
| 338 | + // Initialise protected members | ||
| 339 | + m_tstart = 0; | ||
| 263 | m_name.clear(); | 340 | m_name.clear(); |
| 264 | m_version.clear(); | 341 | m_version.clear(); |
| 265 | m_args.clear(); | 342 | m_args.clear(); |
| 266 | - m_tstart = 0; | 343 | + m_pars.clear(); |
| 344 | + m_chatter = 1; | ||
| 345 | + m_clobber = true; | ||
| 346 | + m_debug = false; | ||
| 267 | 347 | ||
| 268 | // Return | 348 | // Return |
| 269 | return; | 349 | return; |
| @@ -277,11 +357,18 @@ void GApplication::init_members(void) | @@ -277,11 +357,18 @@ void GApplication::init_members(void) | ||
| 277 | ***************************************************************************/ | 357 | ***************************************************************************/ |
| 278 | void GApplication::copy_members(const GApplication& app) | 358 | void GApplication::copy_members(const GApplication& app) |
| 279 | { | 359 | { |
| 280 | - // Copy attributes | 360 | + // Copy public attributes |
| 361 | + log = app.log; | ||
| 362 | + | ||
| 363 | + // Copy protected attributes | ||
| 281 | m_name = app.m_name; | 364 | m_name = app.m_name; |
| 282 | m_version = app.m_version; | 365 | m_version = app.m_version; |
| 283 | m_args = app.m_args; | 366 | m_args = app.m_args; |
| 284 | m_tstart = app.m_tstart; | 367 | m_tstart = app.m_tstart; |
| 368 | + m_pars = app.m_pars; | ||
| 369 | + m_chatter = app.m_chatter; | ||
| 370 | + m_clobber = app.m_clobber; | ||
| 371 | + m_debug = app.m_debug; | ||
| 285 | 372 | ||
| 286 | // Return | 373 | // Return |
| 287 | return; | 374 | return; |
| @@ -293,6 +380,15 @@ void GApplication::copy_members(const GApplication& app) | @@ -293,6 +380,15 @@ void GApplication::copy_members(const GApplication& app) | ||
| 293 | ***************************************************************************/ | 380 | ***************************************************************************/ |
| 294 | void GApplication::free_members(void) | 381 | void GApplication::free_members(void) |
| 295 | { | 382 | { |
| 383 | + // Save application parameters | ||
| 384 | + m_pars.save(par_filename()); | ||
| 385 | + | ||
| 386 | + // Put trailer in log file | ||
| 387 | + log_trailer(); | ||
| 388 | + | ||
| 389 | + // Close log file | ||
| 390 | + log.close(); | ||
| 391 | + | ||
| 296 | // Return | 392 | // Return |
| 297 | return; | 393 | return; |
| 298 | } | 394 | } |
| @@ -300,14 +396,104 @@ void GApplication::free_members(void) | @@ -300,14 +396,104 @@ void GApplication::free_members(void) | ||
| 300 | 396 | ||
| 301 | /***********************************************************************//** | 397 | /***********************************************************************//** |
| 302 | * @brief Returns parameter filename | 398 | * @brief Returns parameter filename |
| 399 | + * | ||
| 400 | + * The parameter filename is given by the task name to which the suffix | ||
| 401 | + * '.par' is added. | ||
| 303 | ***************************************************************************/ | 402 | ***************************************************************************/ |
| 304 | -std::string GApplication::parfilename(void) const | 403 | +std::string GApplication::par_filename(void) const |
| 305 | { | 404 | { |
| 306 | // Return | 405 | // Return |
| 307 | return (m_name+".par"); | 406 | return (m_name+".par"); |
| 308 | } | 407 | } |
| 309 | 408 | ||
| 310 | 409 | ||
| 410 | +/***********************************************************************//** | ||
| 411 | + * @brief Returns log filename | ||
| 412 | + * | ||
| 413 | + * The log filename is given by the task name to which the suffix '.log' is | ||
| 414 | + * added. | ||
| 415 | + ***************************************************************************/ | ||
| 416 | +std::string GApplication::log_filename(void) const | ||
| 417 | +{ | ||
| 418 | + // Return | ||
| 419 | + return (m_name+".log"); | ||
| 420 | +} | ||
| 421 | + | ||
| 422 | + | ||
| 423 | +/***********************************************************************//** | ||
| 424 | + * @brief Get standard parameters from parameter file | ||
| 425 | + ***************************************************************************/ | ||
| 426 | +void GApplication::get_par_standard(void) | ||
| 427 | +{ | ||
| 428 | + // Get parameter pointers (NULL if not found) | ||
| 429 | + GPar* par_chatter = par("chatter"); | ||
| 430 | + GPar* par_clobber = par("clobber"); | ||
| 431 | + GPar* par_debug = par("debug"); | ||
| 432 | + | ||
| 433 | + // Extract parameters if they exist | ||
| 434 | + if (par_chatter != NULL) | ||
| 435 | + m_chatter = par_chatter->integer(); | ||
| 436 | + if (par_clobber != NULL) | ||
| 437 | + m_clobber = par_clobber->boolean(); | ||
| 438 | + if (par_debug != NULL) | ||
| 439 | + m_debug = par_debug->boolean(); | ||
| 440 | + | ||
| 441 | + // Return | ||
| 442 | + return; | ||
| 443 | +} | ||
| 444 | + | ||
| 445 | + | ||
| 446 | +/***********************************************************************//** | ||
| 447 | + * @brief Dump application header in log file | ||
| 448 | + * | ||
| 449 | + * Dump the application header into the log file. The header is composed of | ||
| 450 | + * a fixed width block delimined by '*' characters that contains information | ||
| 451 | + * about the application name and version. | ||
| 452 | + ***************************************************************************/ | ||
| 453 | +void GApplication::log_header(void) | ||
| 454 | +{ | ||
| 455 | + // Reset any indentation | ||
| 456 | + log.indent(0); | ||
| 457 | + | ||
| 458 | + // Dump header | ||
| 459 | + log << fill("*", header_width) << std::endl; | ||
| 460 | + log << "*" << center(m_name, header_width-2) << "*" << std::endl; | ||
| 461 | + log << "* " << fill("-", header_width-4) << " *" << std::endl; | ||
| 462 | + log << "* Version: " << left(m_version, header_width-12) << "*" << std::endl; | ||
| 463 | + log << fill("*", header_width) << std::endl; | ||
| 464 | + | ||
| 465 | + // Return | ||
| 466 | + return; | ||
| 467 | +} | ||
| 468 | + | ||
| 469 | + | ||
| 470 | +/***********************************************************************//** | ||
| 471 | + * @brief Dump application trailer in log file | ||
| 472 | + * | ||
| 473 | + * The application trailer gives the total number of elapsed CPU time. | ||
| 474 | + ***************************************************************************/ | ||
| 475 | +void GApplication::log_trailer(void) | ||
| 476 | +{ | ||
| 477 | + // Get elapsed time | ||
| 478 | + double t = telapse(); | ||
| 479 | + | ||
| 480 | + // Reset any indentation | ||
| 481 | + log.indent(0); | ||
| 482 | + | ||
| 483 | + // Dump trailer | ||
| 484 | + log << "Application \"" << m_name << "\" terminated after"; | ||
| 485 | + log << " consuming " << telapse() << " seconds of CPU time."; | ||
| 486 | + if (t < 0.1) | ||
| 487 | + log << " This was rather quick!"; | ||
| 488 | + if (t > 86400.0) | ||
| 489 | + log << " We hope it was worth waiting ..."; | ||
| 490 | + log << std::endl; | ||
| 491 | + | ||
| 492 | + // Return | ||
| 493 | + return; | ||
| 494 | +} | ||
| 495 | + | ||
| 496 | + | ||
| 311 | /*========================================================================== | 497 | /*========================================================================== |
| 312 | = = | 498 | = = |
| 313 | = Friends = | 499 | = Friends = |