M
ma740988
Faced with the need to instrument/log data I've decided to create an
instrumentation/log class. My initial thoughts (baby steps) on this
instrumentation/log class is as follows:
1. Time Stamping capability
2. A member function that'll take std:stream as an argument and
print all accumulated logs.
# include <iostream>
# include <ctime>
# include <iomanip>
# include <vector>
# include <algorithm>
# include <functional>
# include <iterator>
# include <sstream>
using namespace std; // revisit this
struct PlainPrintPolicy
{
static string print(const string& str) { return str; }
};
struct TimestampPrintPolicy
{
static string print(const string& str);
};
string TimestampPrintPolicy:rint(const string& str)
{
ostringstream ostr;
time_t now;
time(&now);
tm *current = localtime(&now);
ostr.fill('0');
ostr << "["
<< current->tm_year+1900 << "-"
<< setw(2) << current->tm_mon+1 << "-"
<< current->tm_mday << " "
<< setw(2) << current->tm_hour << "."
<< setw(2) << current->tm_min << "."
<< setw(2) << current->tm_sec << "]: "
<< str;
return ostr.str();
}
template <typename PrintPolicy>
class Logger
{
public:
void addEntry(const string& str)
{
store_.push_back(PrintPolicy:rint(str));
}
void dumpLog(ostream& os)
{
copy(store_.begin(), store_.end(),
ostream_iterator<string>(os, "\n"));
}
private:
vector<string> store_;
};
int main()
{
Logger<PlainPrintPolicy> logger;
logger.addEntry("System booted");
logger.addEntry("FaultFaultFault");
logger.addEntry("Shutdown");
logger.dumpLog(cout);
Logger<TimestampPrintPolicy> logger2;
logger2.addEntry("System booted");
logger2.addEntry("FaultFaultFault");
logger2.addEntry("Shutdown");
logger2.dumpLog(cout);
return 0;
}
After investigating I thought - for completeness - I could modify the
existing class to:
3. Add - I'll call it - object registration. The intent here is to
have visibility into member data IRRESPECTIVE of 'class'. One thought
involved a static array of class pointer as a member in any private
class. The constructor registers any new object and the destructor
'de-registers' objects. A monitor utility would have access to the
array and provide information on request.
4. File stream, cout and stringstream log capabilities.
Additional capabilities include:
(1) Log file maximum size, or rollover to new log file at certain
size.
(2) Compress repeated messages.
(3) Prevent runaway repeated forever error messages.
I'm interested in advise primarily with regard to item 3. Item 3 seem
to approach 'policy designs' and I'm not there yet in text I'm reading
(modern C++ design). In addition - based on the requirements - I'm
curious to know if I'm on the right track.
Finally, I'm of the impression that a streambuf-based (deriving from
streambuf) solution would be appealing but 'playing' with streams is -
for now - too advanced for me and falls in the two hard pile.
Note: I suspect this is request for a review/suggestions might be
more of a design question and might be better suited for some other
group but if I've violated any rule, forgive me.
Thanks in advance.
instrumentation/log class. My initial thoughts (baby steps) on this
instrumentation/log class is as follows:
1. Time Stamping capability
2. A member function that'll take std:stream as an argument and
print all accumulated logs.
# include <iostream>
# include <ctime>
# include <iomanip>
# include <vector>
# include <algorithm>
# include <functional>
# include <iterator>
# include <sstream>
using namespace std; // revisit this
struct PlainPrintPolicy
{
static string print(const string& str) { return str; }
};
struct TimestampPrintPolicy
{
static string print(const string& str);
};
string TimestampPrintPolicy:rint(const string& str)
{
ostringstream ostr;
time_t now;
time(&now);
tm *current = localtime(&now);
ostr.fill('0');
ostr << "["
<< current->tm_year+1900 << "-"
<< setw(2) << current->tm_mon+1 << "-"
<< current->tm_mday << " "
<< setw(2) << current->tm_hour << "."
<< setw(2) << current->tm_min << "."
<< setw(2) << current->tm_sec << "]: "
<< str;
return ostr.str();
}
template <typename PrintPolicy>
class Logger
{
public:
void addEntry(const string& str)
{
store_.push_back(PrintPolicy:rint(str));
}
void dumpLog(ostream& os)
{
copy(store_.begin(), store_.end(),
ostream_iterator<string>(os, "\n"));
}
private:
vector<string> store_;
};
int main()
{
Logger<PlainPrintPolicy> logger;
logger.addEntry("System booted");
logger.addEntry("FaultFaultFault");
logger.addEntry("Shutdown");
logger.dumpLog(cout);
Logger<TimestampPrintPolicy> logger2;
logger2.addEntry("System booted");
logger2.addEntry("FaultFaultFault");
logger2.addEntry("Shutdown");
logger2.dumpLog(cout);
return 0;
}
After investigating I thought - for completeness - I could modify the
existing class to:
3. Add - I'll call it - object registration. The intent here is to
have visibility into member data IRRESPECTIVE of 'class'. One thought
involved a static array of class pointer as a member in any private
class. The constructor registers any new object and the destructor
'de-registers' objects. A monitor utility would have access to the
array and provide information on request.
4. File stream, cout and stringstream log capabilities.
Additional capabilities include:
(1) Log file maximum size, or rollover to new log file at certain
size.
(2) Compress repeated messages.
(3) Prevent runaway repeated forever error messages.
I'm interested in advise primarily with regard to item 3. Item 3 seem
to approach 'policy designs' and I'm not there yet in text I'm reading
(modern C++ design). In addition - based on the requirements - I'm
curious to know if I'm on the right track.
Finally, I'm of the impression that a streambuf-based (deriving from
streambuf) solution would be appealing but 'playing' with streams is -
for now - too advanced for me and falls in the two hard pile.
Note: I suspect this is request for a review/suggestions might be
more of a design question and might be better suited for some other
group but if I've violated any rule, forgive me.
Thanks in advance.