00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "PSQt/LoggerBase.h"
00011 #include "PSQt/QGUtils.h"
00012 #include <iomanip>
00013
00014 using namespace std;
00015
00016 namespace PSQt {
00017
00018
00019
00020 LoggerBase::LoggerBase(const LEVEL& level)
00021 : m_recnum(0)
00022 , m_level(level)
00023 {
00024 startLoggerBase();
00025 }
00026
00027
00028
00029 void
00030 LoggerBase::startLoggerBase()
00031 {
00032 m_start_tstamp = strTimeStamp();
00033 m_start_time = doubleTimeNow();
00034 stringstream ss; ss << "Start logger at t[sec] = " << fixed << std::setprecision(9) << m_start_time;
00035 message(_name_(), INFO, ss.str());
00036 }
00037
00038
00039
00040 void
00041 LoggerBase::setLevel(const LEVEL& level)
00042 {
00043 m_level=level;
00044 message(_name_(), DEBUG, "Message level is set to " + strLevel(level));
00045 }
00046
00047
00048
00049 void
00050 LoggerBase::message(const std::string& name, const LEVEL& level, const std::string& msg)
00051 {
00052
00053 Record rec = {++m_recnum, doubleTimeNow(), strTimeStamp(), level, name, msg};
00054 m_sslog[m_recnum] = rec;
00055
00056
00057 if(level < m_level) return;
00058
00059 if(m_level == DEBUG) std::cout << rec.strRecordTotal() << '\n';
00060 new_record(rec);
00061 }
00062
00063
00064
00065 void
00066 LoggerBase::message(const std::string& name, const LEVEL& level, const std::stringstream& ss)
00067 {
00068 message(name, level, ss.str());
00069 }
00070
00071
00072
00073 void
00074 LoggerBase::print(const std::string& str)
00075 {
00076 stringstream ss; ss << strTimeStamp() << " LoggerBase::print():" << str;
00077 std::cout << ss.str() << '\n';
00078 }
00079
00080
00081
00082 std::string
00083 LoggerBase::strRecordsForLevel(const LEVEL& threshold)
00084 {
00085 stringstream ss;
00086 for (std::map<unsigned, Record>::iterator it=m_sslog.begin(); it!=m_sslog.end(); ++it) {
00087 Record& rec = it->second;
00088 if(rec.level<threshold) continue;
00089 ss << rec.strRecord() << '\n';
00090 }
00091 return ss.str();
00092 }
00093
00094
00095
00096 void
00097 LoggerBase::saveLogInFile(const std::string& ofname, const bool& add_tstamp)
00098 {
00099 std::string fname = getFileName(ofname, add_tstamp);
00100
00101 message(_name_(), INFO, "Save this log in the file " + fname);
00102
00103
00104 std::ofstream out(fname.c_str());
00105 if (not out.good()) { message(_name_(), WARNING, "File " + fname + " IS NOT SAVED! - status is not good"); return; }
00106
00107 out << this->strRecordsForLevel(m_level);
00108
00109 out.close();
00110
00111 print(" Log saved in the file " + fname);
00112 }
00113
00114
00115
00116 std::string
00117 LoggerBase::getFileName(const std::string& ofname, const bool& add_tstamp)
00118 {
00119 std::string fname = (ofname==std::string()) ? "log.txt" : ofname;
00120
00121 if (! add_tstamp) return fname;
00122
00123 std::string root;
00124 std::string ext;
00125 splitext(fname, root, ext);
00126 return root + '-' + m_start_tstamp + ext;
00127 }
00128
00129
00130
00131 void
00132 LoggerBase::new_record(Record& rec)
00133 {
00134 if(rec.number < 2) message(_name_(), DEBUG, "new_record() - DEFAULT version of callback method for overloading in subclass");
00135
00136
00137
00138 }
00139
00140
00141
00142
00143
00144
00145
00146 std::string
00147 Record::strRecordTotal()
00148 {
00149 stringstream ss;
00150 ss << left << std::setw(4) << number
00151 << fixed << std::setw(16) << std::setprecision(3) << time
00152 << std::setw(21) << tstamp
00153 << std::setw(16) << name << ' '
00154 << std::setw(10) << strLevel(level)
00155 << msg;
00156 return ss.str();
00157 }
00158
00159
00160
00161 std::string
00162 Record::strRecordBrief()
00163 {
00164 stringstream ss;
00165 ss << left << std::setw(4) << number
00166 << std::setw(21) << tstamp
00167 << std::setw(16) << name << ' '
00168 << std::setw(10) << strLevel(level)
00169 << msg;
00170 return ss.str();
00171 }
00172
00173
00174
00175 std::string
00176 Record::strRecord()
00177 {
00178
00179 return strRecordBrief();
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 std::string
00191 strLevel(const LEVEL& level)
00192 {
00193 if (level == DEBUG ) return "DEBUG";
00194 else if(level == INFO ) return "INFO";
00195 else if(level == WARNING ) return "WARNING";
00196 else if(level == CRITICAL) return "CRITICAL";
00197 else if(level == ERROR ) return "ERROR";
00198 else return "NON-IMPLEMENTED";
00199 }
00200
00201
00202 LEVEL
00203 levelFromString(const std::string& str)
00204 {
00205 if (str == std::string("DEBUG") ) return DEBUG;
00206 else if(str == std::string("INFO") ) return INFO;
00207 else if(str == std::string("WARNING") ) return WARNING;
00208 else if(str == std::string("CRITICAL")) return CRITICAL;
00209 else if(str == std::string("ERROR") ) return ERROR;
00210 else return NONE;
00211 }
00212
00213
00214
00215 std::string strTimeStamp(const std::string& format)
00216 {
00217 time_t time_sec;
00218 time ( &time_sec );
00219 struct tm* timeinfo; timeinfo = localtime ( &time_sec );
00220 char c_time_buf[32]; strftime(c_time_buf, 32, format.c_str(), timeinfo);
00221 return std::string (c_time_buf);
00222 }
00223
00224
00225
00226 double
00227 doubleTimeNow() {
00228 struct timespec tnow;
00229 int status = clock_gettime( CLOCK_REALTIME, &tnow );
00230 return (status) ? 0 : tnow.tv_sec + 1e-9 * tnow.tv_nsec;
00231 }
00232
00233
00234
00235 }
00236
00237
00238
00239