Commit 675697fe authored by fmg005's avatar fmg005

added micro-second precision and setting logging level

parent 40cabc25
#include "CLA_Logger.h"
CLA::LOGGER::LOGGER() {
m_logstream[0].open(prosim_logs_dir+"prosim_"+current_time(false)+".log"); // timestamped logs
m_logstream[1].open(prosim_logs_dir+"duration_"+current_time(false)+".log"); // timestamped logs
m_logstream[1] <<"start time,"<<"end time,"<<"duration(s)\n";
CLA::LOGGER::LOGGER(const string& name): m_patient_name(move(name)){
/* timestamped logs */
m_logstream[0].open(prosim_logs_dir+"prosim_"+m_patient_name+current_time(false)+".log");
m_logstream[1].open(prosim_results_dir+"duration_"+m_patient_name+current_time(false)+".txt");
m_logstream[0] << "Date"<<setw(12)<<"Time"<<setw(12)<<"Tz"<<setw(3)<<" "<<"Level"<<setw(9)<<"Message"<<endl;
m_logstream[1] <<"start time,"<<"end time,"<<"duration(s),"<<"next_update time"<<endl;
/* mapping strings to levels */
logging_levels["DEBUG"] = CLA::LOGGER::DEBUG;
logging_levels["INFO"] = CLA::LOGGER::INFO;
logging_levels["WARN"] = CLA::LOGGER::WARN;
logging_levels["ERROR"] = CLA::LOGGER::ERROR;
logging_levels["FATAL"] = CLA::LOGGER::FATAL;
logging_levels["NONE"] = CLA::LOGGER::NONE;
}
CLA::LOGGER::LOGGER(const string& filename): m_filename(move(filename)) {
m_logstream[0].open(prosim_logs_dir+m_filename, ios::out|ios::binary);
m_logstream[1].open(prosim_logs_dir+"duration_"+m_filename, ios::out|ios::binary);
m_logstream[1] <<"start time,"<<"end time,"<<"duration(s)\n";
CLA::LOGGER::LOGGER(const string& filename, const string& name): m_filename(move(filename)),
m_patient_name(move(name)) {
m_logstream[0].open(prosim_logs_dir+m_filename+".log", ios::out|ios::binary);
m_logstream[1].open(prosim_results_dir+"duration_"+m_filename+".txt", ios::out|ios::binary);
m_logstream[0] << "Date"<<setw(12)<<"Time"<<setw(12)<<"Tz"<<setw(3)<<" "<<"Level"<<setw(9)<<"Message"<<endl;
m_logstream[1] <<"start time,"<<"end time,"<<"duration(s),"<<"next_update time"<<endl;
/* mapping strings to levels */
logging_levels["DEBUG"] = CLA::LOGGER::DEBUG;
logging_levels["INFO"] = CLA::LOGGER::INFO;
logging_levels["WARN"] = CLA::LOGGER::WARN;
logging_levels["ERROR"] = CLA::LOGGER::ERROR;
logging_levels["FATAL"] = CLA::LOGGER::FATAL;
logging_levels["NONE"] = CLA::LOGGER::NONE;
}
string CLA::LOGGER::current_time(bool display_timezone) {
time_t now = time(0);
struct tm* timeinfo;
struct timeval tv; /* for seconds and micro seconds */
gettimeofday(&tv , NULL); /* populate `tv` with time since epoch */
char buffer[50];
timeinfo = localtime(&now);
if (display_timezone)
strftime(buffer, 50, "%Y-%M-%d.%X-%Z", timeinfo);
else
strftime(buffer, 50, "%Y-%M-%d.%X", timeinfo);
char m_sec_buff[10];
char tz_buff[10];
/* this is where the milli seconds come from :) */
uint m_secs = static_cast<uint>(tv.tv_usec)/1000;
sprintf(m_sec_buff, "%.3u", m_secs); /*cast unit to string */
if (display_timezone) {
strftime(buffer, 50, "%Y-%m-%d %X,", localtime(&tv.tv_sec));
strftime(tz_buff, 10, " %Z", localtime(&tv.tv_sec));
strcat(buffer, m_sec_buff);
strcat(buffer, tz_buff);
}
else {
strftime(buffer, 50, "%Y-%m-%d %X", localtime(&tv.tv_sec));
}
return buffer;
}
......@@ -35,16 +61,42 @@ string CLA::LOGGER::format_chrono_time(time_t t) {
string CLA::LOGGER::format_chrono_time(system_clock::time_point t) {
char buff[20];
char m_sec_buff[10];
auto in_time = system_clock::to_time_t(t);
strftime(buff, 20, "%X", localtime(&in_time));
auto milli_secs = duration_cast<milliseconds>(t.time_since_epoch());
uint m_secs = milli_secs.count()%1000;
strftime(buff, 20, "%X.", localtime(&in_time));
sprintf(m_sec_buff, "%d", m_secs);
strcat(buff,m_sec_buff);
return buff;
}
void CLA::LOGGER::log_duration(system_clock::time_point start_time, system_clock::time_point end_time, time_t duration_time) {
m_logstream[1]<<format_chrono_time(start_time)<<","<<format_chrono_time(end_time)<<","<<static_cast<float>(duration_time)/1000<<"\n";
void CLA::LOGGER::log_duration(system_clock::time_point start_time, system_clock::time_point end_time, time_t duration_time,
time_t next_update_time) {
ss<< format_chrono_time(start_time);
ss<< ",";
ss<< format_chrono_time(end_time);
ss<< ",";
ss<< static_cast<float>(duration_time)/1000;
ss<< ",";
ss<<format_chrono_time(next_update_time);
m_logstream[1] << ss.str() << endl;
ss.str("");
}
void CLA::LOGGER::setLevel(const string& level) {
/* all `logging levels` less than `level` in severity will be ignored*/
DEFAULT_LEVEL = logging_levels[level];
}
void CLA::LOGGER::setVerbosity(bool verbosity) {
/* logging details will be be printed streamed to stdout as
* well if `m_verbosity` is set to `true`, else otherwise
*/
m_verbosity = verbosity;
}
string CLA::LOGGER::set_level(LEVEL level) {
string CLA::LOGGER::convert_level_to_string(LEVEL level) {
switch(level) {
case DEBUG:
level_name = "DEBUG";
......@@ -52,8 +104,8 @@ string CLA::LOGGER::set_level(LEVEL level) {
case INFO:
level_name = "INFO";
break;
case WARNING:
level_name = "WARNING";
case WARN:
level_name = "WARN";
break;
case ERROR:
level_name = "ERROR";
......@@ -67,7 +119,8 @@ string CLA::LOGGER::set_level(LEVEL level) {
CLA::LOGGER::~LOGGER() {
for (int i = 0; i < 2; i++) {
m_logstream[i].close();
m_logstream[i].flush();
m_logstream[i].close();
}
ss.clear();
}
......@@ -5,9 +5,14 @@
#include <string>
#include <ctime> /* time_t, time, struct tm, localtime, strftime*/
#include <fstream>
#include <utility>
#include <map>
#include <cstdarg>
#include <sys/time.h>
#include <iomanip>
#include <sstream>
#include <iostream>
#include <cstring> /* strcat() */
#include <sys/time.h> /* timeval, gettimefday*/
#include <chrono>
#include "configure_prosim_paths.h"
......@@ -16,60 +21,112 @@ using namespace std::chrono;
namespace CLA {
class LOGGER {
private:
string level_name;
const string m_filename;
const string m_patient_name;
ofstream m_logstream[2];
ostringstream ss;
enum LEVEL {DEBUG, INFO, WARNING, ERROR, FATAL};
bool m_verbosity = true;
enum LEVEL {DEBUG, INFO, WARN, ERROR, FATAL, NONE};
LEVEL DEFAULT_LEVEL = LOGGER::DEBUG;
string current_time(bool);
string format_chrono_time(time_t);
string format_chrono_time(system_clock::time_point);
string set_level(LEVEL);
string convert_level_to_string(LEVEL);
map<std::string, LEVEL> logging_levels;
public:
LOGGER();
LOGGER(const string&);
void log_duration(system_clock::time_point, system_clock::time_point, time_t);
LOGGER(const string&, const string&);
void log_duration(system_clock::time_point, system_clock::time_point, time_t, time_t);
~LOGGER();
void setLevel(const string&);
void setVerbosity(bool);
template <typename T>
void debug(const T& t) {
ss << t;
m_logstream[0]<<current_time(true)<<","<<set_level(LOGGER::DEBUG)<<","+ss.str()+"\n";
ss.str("");
}
template <typename T>
void info(const T& t) {
ss << t;
m_logstream[0]<<current_time(true)<<","<<set_level(LOGGER::INFO)<<","+ss.str()+"\n";
cout<<current_time(false)<<" ("<<set_level(LOGGER::INFO)<<") "+ss.str()<<endl;
ss.str("");
}
template <typename T>
void warning(const T& t) {
ss << t;
m_logstream[0]<<current_time(true)<<","<<set_level(LOGGER::WARNING)<<","+ss.str()+"\n";
cout<<current_time(false)<<" ("<<set_level(LOGGER::WARNING)<<") "+ss.str()<<endl;
ss.str("");
}
template <typename T>
void debug(const T& t) {
if (LOGGER::DEBUG >= DEFAULT_LEVEL) {
ss<< current_time(true);
ss<< setw(2);
ss<< " ";
ss<< convert_level_to_string(LOGGER::DEBUG);
ss<< setw(2);
ss<< " ";
ss<< t;
m_logstream[0]<< ss.str() << endl;
if (m_verbosity)
cout << ss.str() <<endl;
ss.str("");
}
}
template <typename T>
void error(const T& t) {
ss << t;
m_logstream[0]<<current_time(true)<<","<<set_level(LOGGER::ERROR)<<","+ss.str()+"\n";
ss.str("");
}
template <typename T>
void info(const T& t) {
if (LOGGER::INFO >= DEFAULT_LEVEL) {
ss<< current_time(true);
ss<< setw(2);
ss<< " ";
ss<< convert_level_to_string(LOGGER::INFO);
ss<< setw(2);
ss<< " ";
ss<< " ";
ss<< t;
m_logstream[0]<< ss.str() << endl;
if (m_verbosity)
cout << ss.str() << endl;
ss.str("");
}
}
template <typename T>
void fatal(const T& t) {
ss << t;
m_logstream[0]<<current_time(true)<<","<<set_level(LOGGER::FATAL)<<","+ss.str()+"\n";
ss.str("");
}
template <typename T>
void warn(const T& t) {
if (LOGGER::WARN > DEFAULT_LEVEL) {
ss<< current_time(true);
ss<< setw(2);
ss<< " ";
ss<< convert_level_to_string(LOGGER::WARN);
ss<< setw(2);
ss<< " ";
ss<< " ";
ss<< t;
m_logstream[0]<< ss.str() << endl;
if (m_verbosity)
cout << ss.str() << endl;
ss.str("");
}
}
template <typename T>
void error(const T& t) {
if (LOGGER::ERROR >= DEFAULT_LEVEL) {
ss<< current_time(true);
ss<< setw(2);
ss<< " ";
ss<< convert_level_to_string(LOGGER::ERROR);
ss<< setw(2);
ss<< " ";
ss<< t;
m_logstream[0]<< ss.str() << endl;
if (m_verbosity)
cout << ss.str() << endl;
ss.str("");
}
}
template <typename T>
void fatal(const T& t) {
if (LOGGER::FATAL >= DEFAULT_LEVEL) {
ss<< current_time(true);
ss<< setw(2);
ss<< " ";
ss<< convert_level_to_string(LOGGER::FATAL);
ss<< setw(2);
ss<< " ";
ss<< t;
m_logstream[0]<< ss.str() << endl;
if (m_verbosity)
cout << ss.str() << endl;
ss.str("");
}
}
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment