Commit cfd19b6ec72209e3babe922387cd270dd88cb5b6

Authored by Jürgen Knödlseder
1 parent 1434a486

Add methods for logging in applications (#1828)

The GApplication::log_parameters() method now takes a mandatory GChatter argument to enable displaying of parameters only above a given chattiness level. This avoids a log-level check in the client code. For the same purpose, the GApplication methods log_string(), log_value(), log_header1(), log_header2(), and log_header3() have been introduced (#1828).
ChangeLog
1   -2016-07-29
  1 +2016-08-03
2 2  
3 3 * Version 1.2.0 released
4 4 =========================
5 5  
6   - Fix removal of Python wrappers after make clean (#1826)
7   - Add GModelSpectralExpInvPlaw class (#1800)
8   - Add GModelSpectralPlawEnergyFlux class (#1790)
9   - Rename GModelSpectralPlaw2 to GModelSpectralPlawPhotonFlux (#1790)
  6 + Add methods for logging in applications (#1828)
  7 + Fix removal of Python wrappers after make clean (#1826)
  8 + Add GModelSpectralExpInvPlaw class (#1800)
  9 + Add GModelSpectralPlawEnergyFlux class (#1790)
  10 + Rename GModelSpectralPlaw2 to GModelSpectralPlawPhotonFlux (#1790)
10 11  
11 12  
12 13 2016-07-24
... ...
Makefile.am
... ... @@ -163,6 +163,11 @@ sphinx-install:
163 163 cp -r $(srcdir)/doc/html/_static $(DESTDIR)$(docdir)/html/ ; \
164 164 fi
165 165  
  166 +# Add clean wrappers rule
  167 +clean-wrappers:
  168 + rm -rf $(builddir)/pyext/gammalib/*.py
  169 + rm -rf $(builddir)/pyext/gammalib/*_wrap.cpp
  170 +
166 171 # Add documentation rule:
167 172 doc: doxygen sphinx
168 173  
... ...
1 1 New Features and Important Changes in GammaLib 1.2.0
2 2  
3   -29 July 2016
  3 +3 August 2016
4 4  
5 5  
6 6 1. Introduction
... ... @@ -22,7 +22,11 @@ The following classes have been renamed:
22 22 - GModelSpectralPlawPhotonFlux, was GModelSpectralPlaw2
23 23  
24 24 The following methods have been added:
25   -- ...
  25 +- GApplication::log_string()
  26 +- GApplication::log_value()
  27 +- GApplication::log_header1()
  28 +- GApplication::log_header2()
  29 +- GApplication::log_header3()
26 30  
27 31 The following methods have been removed:
28 32 - ...
... ... @@ -31,7 +35,7 @@ The following methods have been renamed:
31 35 - GModelSpectralPlawPhotonFlux::flux(), was GModelSpectralPlaw2::integral()
32 36  
33 37 The parameters for the following methods have been changed:
34   -- ...
  38 +- GApplication::log_parameters() now has a mandatory GChatter argument
35 39  
36 40 The return value of the following methods has been changed:
37 41 - ...
... ... @@ -46,7 +50,11 @@ removed in a "make clean" if they have been built (#1826).
46 50  
47 51 4. Application module
48 52 ---------------------
49   -None
  53 +The GApplication::log_parameters() method now takes a mandatory GChatter
  54 +argument to enable displaying of parameters only above a given chattiness
  55 +level. This avoids a log-level check in the client code. For the same
  56 +purpose, the GApplication methods log_string(), log_value(), log_header1(),
  57 +log_header2(), and log_header3() have been introduced (#1828).
50 58  
51 59  
52 60 5. Base module
... ...
README.md
1 1 GammaLib information
2 2 ====================
3   -* Version: 1.2.0.dev1 (29 July 2016)
  3 +* Version: 1.2.0.dev1 (3 August 2016)
4 4 * Author: Juergen Knoedlseder (jurgen.knodlseder@irap.omp.eu)
5 5  
6 6 [![Build Status](https://cta-jenkins.irap.omp.eu/buildStatus/icon?job=gammalib-integrate-os)](https://cta-jenkins.irap.omp.eu/job/gammalib-integrate-os/)
... ...
include/GApplication.hpp
... ... @@ -83,7 +83,18 @@ public:
83 83 const std::string& log_filename(void) const;
84 84 void log_header(void);
85 85 void log_trailer(void);
86   - void log_parameters(void);
  86 + void log_string(const GChatter& chatter,
  87 + const std::string& string);
  88 + void log_value(const GChatter& chatter,
  89 + const std::string& name,
  90 + const std::string& value);
  91 + void log_header1(const GChatter& chatter,
  92 + const std::string& header);
  93 + void log_header2(const GChatter& chatter,
  94 + const std::string& header);
  95 + void log_header3(const GChatter& chatter,
  96 + const std::string& header);
  97 + void log_parameters(const GChatter& chatter);
87 98 const bool& need_help(void) const;
88 99 std::string print(const GChatter& chatter = NORMAL) const;
89 100  
... ...
pyext/GApplication.i
... ... @@ -76,7 +76,15 @@ public:
76 76 %rename(_log_filename) log_filename() const;
77 77 %rename(_log_header) log_header();
78 78 %rename(_log_trailer) log_trailer();
79   - %rename(_log_parameters) log_parameters();
  79 + %rename(_log_string) log_string(const GChatter& chatter,
  80 + const std::string& string);
  81 + %rename(_log_header1) log_header1(const GChatter& chatter,
  82 + const std::string& header);
  83 + %rename(_log_header2) log_header2(const GChatter& chatter,
  84 + const std::string& header);
  85 + %rename(_log_header3) log_header3(const GChatter& chatter,
  86 + const std::string& header);
  87 + %rename(_log_parameters) log_parameters(const GChatter& chatter);
80 88 %rename(_need_help) need_help() const;
81 89 %rename(_log) log;
82 90  
... ... @@ -97,7 +105,18 @@ public:
97 105 const std::string& log_filename(void) const;
98 106 void log_header(void);
99 107 void log_trailer(void);
100   - void log_parameters(void);
  108 + void log_string(const GChatter& chatter,
  109 + const std::string& string);
  110 + void log_value(const GChatter& chatter,
  111 + const std::string& name,
  112 + const std::string& value);
  113 + void log_header1(const GChatter& chatter,
  114 + const std::string& header);
  115 + void log_header2(const GChatter& chatter,
  116 + const std::string& header);
  117 + void log_header3(const GChatter& chatter,
  118 + const std::string& header);
  119 + void log_parameters(const GChatter& chatter);
101 120 const bool& need_help(void) const;
102 121  
103 122 // Public members
... ... @@ -106,7 +125,20 @@ public:
106 125  
107 126  
108 127 /***********************************************************************//**
109   - * @brief GApplication class extension
  128 + * @brief GApplication Python class extension
  129 + ***************************************************************************/
  130 +%pythoncode %{
  131 +# Log the value of a parameter
  132 +def _log_value(self, name, value):
  133 + self._log.parformat(str(name))
  134 + self._log(str(value))
  135 + self._log('\n')
  136 +GApplication._log_value = _log_value
  137 +%}
  138 +
  139 +
  140 +/***********************************************************************//**
  141 + * @brief GApplication C++ class extension
110 142 ***************************************************************************/
111 143 %extend GApplication {
112 144 GApplicationPar& __getitem__(const std::string& name) {
... ...
src/app/GApplication.cpp
... ... @@ -498,50 +498,179 @@ void GApplication::log_trailer(void)
498 498  
499 499  
500 500 /***********************************************************************//**
  501 + * @brief Write string in log file
  502 + *
  503 + * @param[in] chatter Minimum required chattiness
  504 + * @param[in] string String
  505 + *
  506 + * Writes a string into the log file if chattiness is at least @p chatter.
  507 + ***************************************************************************/
  508 +void GApplication::log_string(const GChatter& chatter,
  509 + const std::string& string)
  510 +{
  511 + // Get chattiness of application
  512 + GChatter chattiness = static_cast<GChatter>((&m_pars["chatter"])->integer());
  513 +
  514 + // Only write message if chattiness is at least equal to the minimum
  515 + // required chattiness
  516 + if (chattiness >= chatter) {
  517 + log << string;
  518 + }
  519 +
  520 + // Return
  521 + return;
  522 +}
  523 +
  524 +
  525 +/***********************************************************************//**
  526 + * @brief Write parameter value in log file
  527 + *
  528 + * @param[in] chatter Minimum required chattiness
  529 + * @param[in] name Parameter name string
  530 + * @param[in] value Value string
  531 + *
  532 + * Writes a parameter value into the log file if chattiness is at least
  533 + * @p chatter.
  534 + ***************************************************************************/
  535 +void GApplication::log_value(const GChatter& chatter,
  536 + const std::string& name,
  537 + const std::string& value)
  538 +{
  539 + // Get chattiness of application
  540 + GChatter chattiness = static_cast<GChatter>((&m_pars["chatter"])->integer());
  541 +
  542 + // Only write message if chattiness is at least equal to the minimum
  543 + // required chattiness
  544 + if (chattiness >= chatter) {
  545 + log << gammalib::parformat(name);
  546 + log << value << std::endl;
  547 + }
  548 +
  549 + // Return
  550 + return;
  551 +}
  552 +
  553 +
  554 +/***********************************************************************//**
  555 + * @brief Write header 1 in log file
  556 + *
  557 + * @param[in] chatter Minimum required chattiness
  558 + * @param[in] header Header string
  559 + *
  560 + * Writes a header of level 1 into the log file if chattiness is at least
  561 + * @p chatter.
  562 + ***************************************************************************/
  563 +void GApplication::log_header1(const GChatter& chatter,
  564 + const std::string& header)
  565 +{
  566 + // Get chattiness of application
  567 + GChatter chattiness = static_cast<GChatter>((&m_pars["chatter"])->integer());
  568 +
  569 + // Only write message if chattiness is at least equal to the minimum
  570 + // required chattiness
  571 + if (chattiness >= chatter) {
  572 + log << std::endl;
  573 + log.header1(header);
  574 + }
  575 +
  576 + // Return
  577 + return;
  578 +}
  579 +
  580 +
  581 +/***********************************************************************//**
  582 + * @brief Write header 2 in log file
  583 + *
  584 + * @param[in] chatter Minimum required chattiness
  585 + * @param[in] header Header string
  586 + *
  587 + * Writes a header of level 2 into the log file if chattiness is at least
  588 + * @p chatter.
  589 + ***************************************************************************/
  590 +void GApplication::log_header2(const GChatter& chatter,
  591 + const std::string& header)
  592 +{
  593 + // Get chattiness of application
  594 + GChatter chattiness = static_cast<GChatter>((&m_pars["chatter"])->integer());
  595 +
  596 + // Only write message if chattiness is at least equal to the minimum
  597 + // required chattiness
  598 + if (chattiness >= chatter) {
  599 + log << std::endl;
  600 + log.header2(header);
  601 + }
  602 +
  603 + // Return
  604 + return;
  605 +}
  606 +
  607 +
  608 +/***********************************************************************//**
  609 + * @brief Write header 3 in log file
  610 + *
  611 + * @param[in] chatter Minimum required chattiness
  612 + * @param[in] header Header string
  613 + *
  614 + * Writes a header of level 3 into the log file if chattiness is at least
  615 + * @p chatter.
  616 + ***************************************************************************/
  617 +void GApplication::log_header3(const GChatter& chatter,
  618 + const std::string& header)
  619 +{
  620 + // Get chattiness of application
  621 + GChatter chattiness = static_cast<GChatter>((&m_pars["chatter"])->integer());
  622 +
  623 + // Only write message if chattiness is at least equal to the minimum
  624 + // required chattiness
  625 + if (chattiness >= chatter) {
  626 + log << std::endl;
  627 + log.header3(header);
  628 + }
  629 +
  630 + // Return
  631 + return;
  632 +}
  633 +
  634 +
  635 +/***********************************************************************//**
501 636 * @brief Write application parameters in log file
502 637 *
  638 + * @param[in] chatter Minimum required chattiness
  639 + *
503 640 * Writes all application parameters in the log file. For parameters that
504 641 * have not yet been queried the method does not write the current value
505 642 * but signals [not queried].
506 643 ***************************************************************************/
507   -void GApplication::log_parameters(void)
  644 +void GApplication::log_parameters(const GChatter& chatter)
508 645 {
509   - // Write header
510   - log.header1("Parameters");
511   -
512   - // Count number of written parameters
513   - int written = 0;
  646 + // Get chattiness of application
  647 + GChatter chattiness = static_cast<GChatter>((&m_pars["chatter"])->integer());
514 648  
515   - // Write parameters in logger
516   - for (int i = 0; i < m_pars.size(); ++i) {
  649 + // Only write parameters if the chattiness is at least equal to the
  650 + // minimum required chattiness
  651 + if (chattiness >= chatter) {
517 652  
518   - // Skip all parameters that still need to be queried as we
519   - // do not yet know their value
520   - //if (m_pars.m_pars[i].is_query()) {
521   - // continue;
522   - //}
  653 + // Write header
  654 + log.header1("Parameters");
523 655  
524   - // Add line feed
525   - if (written > 0) {
526   - log << std::endl;
527   - }
  656 + // Write parameters in logger
  657 + for (int i = 0; i < m_pars.size(); ++i) {
528 658  
529   - // Set parameter name
530   - std::string name = " " + m_pars.m_pars[i].name() + " ";
531   - name = name + gammalib::fill(".", 28-name.length()) + ": ";
  659 + // Set parameter name
  660 + std::string name = " " + m_pars.m_pars[i].name() + " ";
  661 + name = name + gammalib::fill(".", 28-name.length()) + ": ";
532 662  
533   - // Write parameter
534   - if (m_pars.m_pars[i].is_query()) {
535   - log << name << "[not queried]";
536   - }
537   - else {
538   - log << name << m_pars.m_pars[i].m_value;
539   - }
  663 + // Write parameter
  664 + if (m_pars.m_pars[i].is_query()) {
  665 + log << name << "[not queried]" << std::endl;
  666 + }
  667 + else {
  668 + log << name << m_pars.m_pars[i].m_value << std::endl;
  669 + }
540 670  
541   - // Increment number of written parameters
542   - written++;
  671 + } // endfor: looped over all parameters
543 672  
544   - }
  673 + } // endif: chattiness satisfied minimum required level
545 674  
546 675 // Return
547 676 return;
... ... @@ -551,7 +680,7 @@ void GApplication::log_parameters(void)
551 680 /***********************************************************************//**
552 681 * @brief Print application
553 682 *
554   - * @param[in] chatter Chattiness (defaults to NORMAL).
  683 + * @param[in] chatter Chattiness.
555 684 * @return String containing application information.
556 685 ***************************************************************************/
557 686 std::string GApplication::print(const GChatter& chatter) const
... ...
test/data/test_GApplication.par 0 → 100644
  1 +#
  2 +# Standard parameters
  3 +#====================
  4 +chatter, i, h, 2,0,4, "Chattiness of output"
  5 +clobber, b, h, yes,,, "Overwrite existing output files with new output files?"
  6 +debug, b, h, no,,, "Debugging mode activated"
  7 +mode, s, h, ql,,, "Mode of automatic parameters"
  8 +logfile, f, h, test_logfile.log,,, "Log filename"
... ...
test/test_GApplication.cpp
... ... @@ -28,6 +28,8 @@
28 28 #ifdef HAVE_CONFIG_H
29 29 #include <config.h>
30 30 #endif
  31 +#include <cstdlib> // setenv
  32 +#include <cstdio>
31 33 #include "test_GApplication.hpp"
32 34  
33 35 /* __ Globals ____________________________________________________________ */
... ... @@ -50,6 +52,8 @@ void TestGApplication::set(void)
50 52 "Test C logger");
51 53 append(static_cast<pfunction>(&TestGApplication::test_GApplicationPar),
52 54 "Test GApplicationPar class");
  55 + append(static_cast<pfunction>(&TestGApplication::test_GApplication),
  56 + "Test GApplication class");
53 57  
54 58 // Return
55 59 return;
... ... @@ -355,11 +359,163 @@ void TestGApplication::test_GApplicationPar(void)
355 359 }
356 360  
357 361  
  362 +/***********************************************************************//**
  363 + * @brief Test GApplication class
  364 + **************************************************************************/
  365 +void TestGApplication::test_GApplication(void)
  366 +{
  367 + // Allocate application
  368 + GApplication app1("test_GApplication", "1.0.0");
  369 +
  370 + // Test name and version
  371 + test_value(app1.name(), "test_GApplication", "Check application name");
  372 + test_value(app1.version(), "1.0.0", "Check application version");
  373 +
  374 + // Open log file
  375 + app1.logFileOpen();
  376 +
  377 + // Test log filename
  378 + test_value(app1.par_filename(), "test_GApplication.par",
  379 + "Check application parameter file name");
  380 + test_value(app1.log_filename(), "test_logfile.log",
  381 + "Check application log file name");
  382 +
  383 + // Write something into the logfile and close it
  384 + app1.log_header();
  385 + app1.log_string(SILENT, "Silent");
  386 + app1.log_string(TERSE, "Terse");
  387 + app1.log_string(NORMAL, "Normal");
  388 + app1.log_string(EXPLICIT, "Explicit");
  389 + app1.log_string(VERBOSE, "Verbose");
  390 + app1.log_string(TERSE, "\n");
  391 + app1.log_value(NORMAL, "User parameter", "3.14");
  392 + app1.log_value(VERBOSE, "Verbose parameter", "3.14!!");
  393 + app1.log_header1(NORMAL, "Header 1");
  394 + app1.log_header2(NORMAL, "Header 2");
  395 + app1.log_header3(NORMAL, "Header 3");
  396 + app1.log_header1(VERBOSE, "Verbose header 1");
  397 + app1.log_header2(VERBOSE, "Verbose header 2");
  398 + app1.log_header3(VERBOSE, "Verbose header 3");
  399 + app1.log_parameters(NORMAL);
  400 + app1.log_parameters(VERBOSE);
  401 + app1.log_trailer();
  402 + app1.logFileClose();
  403 +
  404 + // Check if log file exists
  405 + char line[200];
  406 + FILE *fp = fopen("test_logfile.log", "r");
  407 + test_assert(fp != NULL, "Check if logfile exists");
  408 +
  409 + // If log file exists then check it line by line
  410 + if (fp != NULL) {
  411 +
  412 + // Test header
  413 + fgets(line, 100, fp);
  414 + test_value(line, "***************************************************"
  415 + "*****************************\n",
  416 + "Check log file line 1");
  417 + fgets(line, 100, fp);
  418 + test_value(line, "* test_GApplication "
  419 + " *\n",
  420 + "Check log file line 2");
  421 + fgets(line, 100, fp);
  422 + test_value(line, "* -------------------------------------------------"
  423 + "--------------------------- *\n",
  424 + "Check log file line 3");
  425 + fgets(line, 100, fp);
  426 + test_value(line, "* Version: 1.0.0 "
  427 + " *\n",
  428 + "Check log file line 4");
  429 + fgets(line, 100, fp);
  430 + test_value(line, "***************************************************"
  431 + "*****************************\n",
  432 + "Check log file line 5");
  433 +
  434 + // Test logging of strings
  435 + fgets(line, 100, fp);
  436 + test_value(line, "SilentTerseNormal\n", "Check log file line 6");
  437 +
  438 + // Test logging of user parameter
  439 + fgets(line, 100, fp);
  440 + test_value(line, " User parameter ............: 3.14\n",
  441 + "Check log file line 7");
  442 +
  443 + // Test logging of header 1
  444 + fgets(line, 100, fp);
  445 + test_value(line, "\n", "Check log file line 8");
  446 + fgets(line, 100, fp);
  447 + test_value(line, "+==========+\n", "Check log file line 9");
  448 + fgets(line, 100, fp);
  449 + test_value(line, "| Header 1 |\n", "Check log file line 10");
  450 + fgets(line, 100, fp);
  451 + test_value(line, "+==========+\n", "Check log file line 11");
  452 +
  453 + // Test logging of header 2
  454 + fgets(line, 100, fp);
  455 + test_value(line, "\n", "Check log file line 12");
  456 + fgets(line, 100, fp);
  457 + test_value(line, "+----------+\n", "Check log file line 13");
  458 + fgets(line, 100, fp);
  459 + test_value(line, "| Header 2 |\n", "Check log file line 14");
  460 + fgets(line, 100, fp);
  461 + test_value(line, "+----------+\n", "Check log file line 15");
  462 +
  463 + // Test logging of header 3
  464 + fgets(line, 100, fp);
  465 + test_value(line, "\n", "Check log file line 16");
  466 + fgets(line, 100, fp);
  467 + test_value(line, "=== Header 3 ===\n", "Check log file line 17");
  468 +
  469 + // Test logging of parameters
  470 + fgets(line, 100, fp);
  471 + test_value(line, "+============+\n", "Check log file line 18");
  472 + fgets(line, 100, fp);
  473 + test_value(line, "| Parameters |\n", "Check log file line 19");
  474 + fgets(line, 100, fp);
  475 + test_value(line, "+============+\n", "Check log file line 20");
  476 + fgets(line, 100, fp);
  477 + test_value(line, " chatter ...................: 2\n",
  478 + "Check log file line 21");
  479 + fgets(line, 100, fp);
  480 + test_value(line, " clobber ...................: yes\n",
  481 + "Check log file line 22");
  482 + fgets(line, 100, fp);
  483 + test_value(line, " debug .....................: no\n",
  484 + "Check log file line 23");
  485 + fgets(line, 100, fp);
  486 + test_value(line, " mode ......................: ql\n",
  487 + "Check log file line 24");
  488 + fgets(line, 100, fp);
  489 + test_value(line, " logfile ...................: test_logfile.log\n",
  490 + "Check log file line 25");
  491 + fgets(line, 32, fp);
  492 + test_value(line, "Application \"test_GApplication\"",
  493 + "Check log file line 26");
  494 + // Empty remaining characters (not checked since they are machine
  495 + // dependent)
  496 + fgets(line, 200, fp);
  497 + fgets(line, 32, fp);
  498 + test_value(line, "Application \"test_GApplication\"",
  499 + "Check log file line 27");
  500 +
  501 + // Close log file
  502 + fclose(fp);
  503 +
  504 + } // endif: log file existed
  505 +
  506 + // Return
  507 + return;
  508 +}
  509 +
  510 +
358 511 /***************************************************************************
359 512 * @brief Main entry point for test executable
360 513 ***************************************************************************/
361 514 int main(void)
362 515 {
  516 + // Set PFILES environment variable
  517 + setenv("PFILES", "data", 1);
  518 +
363 519 // Allocate test suit container
364 520 GTestSuites testsuites("GApplication");
365 521  
... ...
test/test_GApplication.hpp
1 1 /***************************************************************************
2 2 * test_GApplication.hpp - Test GApplication class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2012-2013 by Jean-Baptiste Cayrou *
  4 + * copyright (C) 2012-2016 by Jean-Baptiste Cayrou *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -51,6 +51,7 @@ public:
51 51 void test_stream_logger(void);
52 52 void test_C_logger(void);
53 53 void test_GApplicationPar(void);
  54 + void test_GApplication(void);
54 55 };
55 56  
56 57 #endif /* TEST_GAPPLICATION_HPP */
... ...