Skip to content
Snippets Groups Projects
Commit 4f25511e authored by Giovanni La Mura's avatar Giovanni La Mura
Browse files

Implement recursive message stacking management

parent 50e8c729
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,10 @@ ...@@ -17,6 +17,10 @@
#include "../include/errors.h" #include "../include/errors.h"
#endif #endif
#ifndef INCLUDE_LOGGING_H_
#include "../include/logging.h"
#endif
#ifndef INCLUDE_CONFIGURATION_H_ #ifndef INCLUDE_CONFIGURATION_H_
#include "../include/Configuration.h" #include "../include/Configuration.h"
#endif #endif
...@@ -50,13 +54,15 @@ using namespace std; ...@@ -50,13 +54,15 @@ using namespace std;
* \param output_path: `string` Directory to write the output files in. * \param output_path: `string` Directory to write the output files in.
*/ */
void cluster(string config_file, string data_file, string output_path) { void cluster(string config_file, string data_file, string output_path) {
printf("INFO: making legacy configuration..."); Logger logger(LOG_INFO);
logger.log("INFO: making legacy configuration...", LOG_INFO);
ScattererConfiguration *sconf = NULL; ScattererConfiguration *sconf = NULL;
try { try {
sconf = ScattererConfiguration::from_dedfb(config_file); sconf = ScattererConfiguration::from_dedfb(config_file);
} catch(const OpenConfigurationFileException &ex) { } catch(const OpenConfigurationFileException &ex) {
printf("\nERROR: failed to open scatterer configuration file.\n"); logger.err("\nERROR: failed to open scatterer configuration file.\n");
printf("FILE: %s\n", ex.what()); string message = "FILE: " + string(ex.what()) + "\n";
logger.err(message);
exit(1); exit(1);
} }
sconf->write_formatted(output_path + "/c_OEDFB"); sconf->write_formatted(output_path + "/c_OEDFB");
...@@ -66,12 +72,13 @@ void cluster(string config_file, string data_file, string output_path) { ...@@ -66,12 +72,13 @@ void cluster(string config_file, string data_file, string output_path) {
try { try {
gconf = GeometryConfiguration::from_legacy(data_file); gconf = GeometryConfiguration::from_legacy(data_file);
} catch (const OpenConfigurationFileException &ex) { } catch (const OpenConfigurationFileException &ex) {
printf("\nERROR: failed to open geometry configuration file.\n"); logger.err("\nERROR: failed to open geometry configuration file.\n");
printf("FILE: %s\n", ex.what()); string message = "FILE: " + string(ex.what()) + "\n";
logger.err(message);
if (sconf) delete sconf; if (sconf) delete sconf;
exit(1); exit(1);
} }
printf(" done.\n"); logger.log(" done.\n", LOG_INFO);
if (sconf->number_of_spheres == gconf->number_of_spheres) { if (sconf->number_of_spheres == gconf->number_of_spheres) {
// Shortcuts to variables stored in configuration objects // Shortcuts to variables stored in configuration objects
int nsph = gconf->number_of_spheres; int nsph = gconf->number_of_spheres;
...@@ -279,9 +286,9 @@ void cluster(string config_file, string data_file, string output_path) { ...@@ -279,9 +286,9 @@ void cluster(string config_file, string data_file, string output_path) {
tppoan.open(tppoan_name.c_str(), ios::out | ios::binary); tppoan.open(tppoan_name.c_str(), ios::out | ios::binary);
if (tppoan.is_open()) { if (tppoan.is_open()) {
#ifdef USE_LAPACK #ifdef USE_LAPACK
printf("INFO: using LAPACK calls.\n"); logger.log("INFO: using LAPACK calls.\n", LOG_INFO);
#else #else
printf("INFO: using fall-back lucin() calls.\n"); logger.log("INFO: using fall-back lucin() calls.\n", LOG_INFO);
#endif #endif
tppoan.write(reinterpret_cast<char *>(&iavm), sizeof(int)); tppoan.write(reinterpret_cast<char *>(&iavm), sizeof(int));
tppoan.write(reinterpret_cast<char *>(&isam), sizeof(int)); tppoan.write(reinterpret_cast<char *>(&isam), sizeof(int));
...@@ -299,7 +306,9 @@ void cluster(string config_file, string data_file, string output_path) { ...@@ -299,7 +306,9 @@ void cluster(string config_file, string data_file, string output_path) {
fprintf(output, " \n"); fprintf(output, " \n");
} }
for (int jxi488 = 1; jxi488 <= nxi; jxi488++) { for (int jxi488 = 1; jxi488 <= nxi; jxi488++) {
printf("INFO: running scale iteration %d of %d...", jxi488, nxi); string message = ("INFO: running scale iteration " + to_string(jxi488)
+ " of " + to_string(nxi) + "...");
logger.log(message, LOG_INFO);
int jaw = 1; int jaw = 1;
fprintf(output, "========== JXI =%3d ====================\n", jxi488); fprintf(output, "========== JXI =%3d ====================\n", jxi488);
double xi = sconf->scale_vec[jxi488 - 1]; double xi = sconf->scale_vec[jxi488 - 1];
...@@ -349,6 +358,7 @@ void cluster(string config_file, string data_file, string output_path) { ...@@ -349,6 +358,7 @@ void cluster(string config_file, string data_file, string output_path) {
} }
if (jer != 0) break; if (jer != 0) break;
} // i132 loop } // i132 loop
logger.push("DEBUG: " + TOSTRING(cms(am, c1, c1ao, c4, c6);));
cms(am, c1, c1ao, c4, c6); cms(am, c1, c1ao, c4, c6);
invert_matrix(am, ndit, jer, mxndm); invert_matrix(am, ndit, jer, mxndm);
if (jer != 0) break; // jxi488 loop: goes to memory clean if (jer != 0) break; // jxi488 loop: goes to memory clean
...@@ -904,11 +914,11 @@ void cluster(string config_file, string data_file, string output_path) { ...@@ -904,11 +914,11 @@ void cluster(string config_file, string data_file, string output_path) {
} // jph484 loop } // jph484 loop
th += thstp; th += thstp;
} // jth486 loop } // jth486 loop
printf(" done.\n"); logger.log(" done.\n", LOG_INFO);
} // jxi488 loop } // jxi488 loop
tppoan.close(); tppoan.close();
} else { // In case TPPOAN could not be opened. Should never happen. } else { // In case TPPOAN could not be opened. Should never happen.
printf("\nERROR: failed to open TPPOAN file.\n"); logger.err("\nERROR: failed to open TPPOAN file.\n");
} }
fclose(output); fclose(output);
// Clean memory // Clean memory
...@@ -992,5 +1002,6 @@ void cluster(string config_file, string data_file, string output_path) { ...@@ -992,5 +1002,6 @@ void cluster(string config_file, string data_file, string output_path) {
} }
delete sconf; delete sconf;
delete gconf; delete gconf;
printf("Finished: output written to %s.\n", (output_path + "/c_OCLU").c_str()); logger.flush(LOG_INFO);
logger.log("Finished: output written to " + output_path + "/c_OCLU\n");
} }
...@@ -7,11 +7,18 @@ ...@@ -7,11 +7,18 @@
#ifndef INCLUDE_LOGGING_H_ #ifndef INCLUDE_LOGGING_H_
#define INCLUDE_LOGGING_H_ #define INCLUDE_LOGGING_H_
//! \brief Debug level logging (maximum verbosity).
#define LOG_DEBG 0 #define LOG_DEBG 0
//! \brief Standard information level logging (default).
#define LOG_INFO 1 #define LOG_INFO 1
//! \brief Warning level logging (almost quiet).
#define LOG_WARN 2 #define LOG_WARN 2
//! \brief Error level logging (silent, unless in pain).
#define LOG_ERRO 3 #define LOG_ERRO 3
//! \brief Macro to stringize code lines
#define TOSTRING(ARG) string(#ARG)
/*! \brief Logger class. /*! \brief Logger class.
* *
* Loggers are objects used to track the execution of a code, reporting activities * Loggers are objects used to track the execution of a code, reporting activities
...@@ -23,9 +30,16 @@ ...@@ -23,9 +30,16 @@
*/ */
class Logger { class Logger {
protected: protected:
FILE *log_output; //! \brief Pointer to error stream.
FILE *err_output; FILE *err_output;
//! \brief Pointer to logging stream.
FILE *log_output;
//! \brief Last logged message.
std::string last_message;
//! \brief Threshold of logging level.
int log_threshold; int log_threshold;
//! \brief Number of identical message repetitions.
long repetitions;
public: public:
/*! \brief Logger instance constructor. /*! \brief Logger instance constructor.
...@@ -47,12 +61,30 @@ class Logger { ...@@ -47,12 +61,30 @@ class Logger {
*/ */
void err(std::string message); void err(std::string message);
/*! \brief Print a summary of recurrent messages and clear the stack.
*
* \param level: `int` The priority level (default is `LOG_DEBG = 0`).
*/
void flush(int level=LOG_DEBG);
/*! \brief Print a message, depending on its logging level. /*! \brief Print a message, depending on its logging level.
* *
* \param message: `string` The message to be printed. * \param message: `string` The message to be printed.
* \param level: `int` The priority level (default is `LOG_INFO = 1`). * \param level: `int` The priority level (default is `LOG_INFO = 1`).
*/ */
void log(std::string message, int level=LOG_INFO); void log(std::string message, int level=LOG_INFO);
/*! \brief Push a recurrent message to the message stack.
*
* When a long stream of identical messages is expected, it may be more
* convenient to put them in a stack. The stack is the error output stream,
* so that no memory is consumed. After the call stack is over, or is the
* message changes, the stack is flushed, meaning that a summary message
* is written to the logging output and the stack counter is reset to 0.
*
* \param message: `string` The message to be stacked.
*/
void push(std::string message);
}; };
#endif #endif
...@@ -14,18 +14,42 @@ ...@@ -14,18 +14,42 @@
using namespace std; using namespace std;
Logger::Logger(int threshold, FILE *logging_output, FILE *error_output) { Logger::Logger(int threshold, FILE *logging_output, FILE *error_output) {
last_message = "";
log_threshold = threshold; log_threshold = threshold;
log_output = logging_output; log_output = logging_output;
err_output = error_output; err_output = error_output;
repetitions = 0;
} }
void Logger::err(std::string message) { void Logger::err(std::string message) {
fprintf(err_output, "%s\n", message.c_str()); fprintf(err_output, "%s", message.c_str());
}
void Logger::flush(int level) {
string summary = "\"" + last_message + "\" issued " + to_string(repetitions);
if (repetitions == 1) summary += " time.\n";
else summary += " times.\n";
if (level == LOG_ERRO) err(summary);
else {
if (level >= log_threshold) fprintf(log_output, "%s", summary.c_str());
}
repetitions = 0;
} }
void Logger::log(std::string message, int level) { void Logger::log(std::string message, int level) {
if (level == LOG_ERRO) err(message); if (level == LOG_ERRO) err(message);
else { else {
if (level >= log_threshold) fprintf(log_output, "%s\n", message.c_str()); if (level >= log_threshold) fprintf(log_output, "%s", message.c_str());
}
}
void Logger::push(std::string message) {
if (repetitions > 0) {
if (message.compare(last_message) != 0) {
flush(LOG_DEBG);
}
} }
log(message, LOG_DEBG);
last_message = message;
repetitions++;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment