how to temporarily use std::cout in place of std::ofstream - c++

if I want to create a logging class, say
class logging_class {
public:
std::ofstream error;
std::ofstream event;
logging_class() {}
logging_class(string err, string evt) {
error.open(err);
event.open(evt);
}
~logging_class() {
error.close();
event.close();
}
};
so that later I can easily create program log:
logging_class logger("Log_Error.txt","Log_Event.txt");
logger.error << "something wrong";
logger.event << "something interesting";
Now, at the early stage of development, I want to redirect all the output to screen (i.e. std::cout). I don't want to change the usage of logger.error<<"something wrong"; to std::cout<<"something wrong";, because later I will need to change all instances of std::cout to either logger.error or logger.event (maybe thousands of them). Can I make some easy changes in the class logger to do this?
Update: Following Enlico's instruction, I can modify the logging_class as:
class logging_class {
public:
//std::ofstream error;
//std::ofstream event;
std::ostream& error;
std::ostream& event;
logging_class():error(std::cout),event(std::cout) {}
//logging_class(string err, string evt) {
// error.open(err);
// event.open(evt);
//}
//~logging_class() {
// error.close();
// event.close();
//}
};
and after creating object with default constructor:
logging_class logger;
I can now redirect all the logging to screen display.

Think of std::cout of what it actually is: an object. It is just that:
The global objects std::cout and std::wcout control output to […]
So when you say that you want to temporarily use std::cout in place of std::ofstream you're mixing apples (object std::cout) with oranges (class std::ofstream).
What you want to do, instead, is to use std::cout instead of an object of class std::ofstream.
But std::cout is not of class std::ofstream, so error can't hold it; it is of class std::ostream, which is a superclass of the former.
Therefore, as suggested in a comment, you can make error/event references to an object of that class, std::ofstreamstd::ostream&, and initialize them with std::cout or with std::ofstream{"filename.txt"} via an appropriate constructor of the logging_class.

Related

How to overload << operator for thread-safe logging in C++?

I'm writing a sketch of a simple thread-safe logging library and some things came on my mind. Here's the code:
#ifndef SimpleLogger_H
#define SimpleLogger_H
#include <iostream>
#include <mutex>
class SimpleLogger
{
public:
template <typename T>
static void log(T message)
{
mutex.lock();
std::cout << message;
mutex.unlock();
}
private:
static std::mutex mutex;
}LOG;
template <typename T>
SimpleLogger &operator<<(SimpleLogger &simpleLogger, T message)
{
simpleLogger.log(message);
return simpleLogger;
}
#endif //SimpleLogger_H
My idea is to use it like this:
LOG << "hello" << " world " << 8 << " I can mix integers and strings";
I understand that the line above is like the following:
auto a1 = LOG.operator<<("hello");
auto a2 = a1.operator<<(" world ");
//Another thread may want to use LOG here, and would print in the middle of my message
auto a3 = a2.operator<<(8);
auto a4 = a3.operator<<(" I can mix integers and strings");
As you can see, because << is broken into several funciton calls, there's a risk that a thread can use the LOG object in the middle of my message (I consider a message the entire cascade of << on one line)
Also, is there a way to automatically add an std::endl for the last << call? I couldn't think of a way to do this, but I saw that some logging libraries have this functionality
How do I solve these two problems?
I know it'd be preferable to use a logging library but I want to mix android, desktop and ios logging in one simple lib without need for high performance, and I'm also puzzled by how I can overcome the difficulties I encountered while writing my own
As others already mentioned, you need a local buffer to collect message before sending to the log file. In the example below, SimpleLoggerBuffer objects are designed to be used as temporary variable only. I.e. it gets destroyed at the end of the expression. The destructor flushes the buffer into the log so that you don't have to explicitly call a flush function (you may add endl there as well if you wish)
#include <iostream>
#include <sstream>
#include <mutex>
using namespace std;
class SimpleLogger
{
public:
template <typename T>
static void log(T& message)
{
mutex.lock();
std::cout << message.str();
message.flush();
mutex.unlock();
}
private:
static std::mutex mutex;
}LOG;
std::mutex SimpleLogger::mutex;
struct SimpleLoggerBuffer{
stringstream ss;
SimpleLoggerBuffer() = default;
SimpleLoggerBuffer(const SimpleLoggerBuffer&) = delete;
SimpleLoggerBuffer& operator=(const SimpleLoggerBuffer&) = delete;
SimpleLoggerBuffer& operator=(SimpleLoggerBuffer&&) = delete;
SimpleLoggerBuffer(SimpleLoggerBuffer&& buf): ss(move(buf.ss)) {
}
template <typename T>
SimpleLoggerBuffer& operator<<(T&& message)
{
ss << std::forward<T>(message);
return *this;
}
~SimpleLoggerBuffer() {
LOG.log(ss);
}
};
template <typename T>
SimpleLoggerBuffer operator<<(SimpleLogger &simpleLogger, T&& message)
{
SimpleLoggerBuffer buf;
buf.ss << std::forward<T>(message);
return buf;
}
int main() {
LOG << "hello" << " world " << 8 << " I can mix integers and strings";
}
You could create a helper class that collects all the output and prints on destruction. Outline:
#include <string>
#include <iostream>
struct Msg;
struct Log {
void print(const Msg &m);
};
struct Msg {
std::string m;
Log &l;
Msg(Log &l) : l(l) {}
~Msg() {
// Print the message on destruction
l.print(*this);
}
};
void Log::print(const Msg &m) {
// Logger specific printing... here, append newline
std::cout << m.m << std::endl;
}
Msg &&operator << (Msg &&m, const std::string &s) {
// Append operator
m.m += s;
return std::move(m);
}
// Helper to log on a specific logger. Just creates the initial message
Msg log(Log &l) { return Msg(l); }
int main()
{
Log l;
log(l) << "a" << "b" << "c";
return 0;
}
As the Msg is local, other threads will not interfere with it. Any necessary locking can be done in the Log.print method, which will receive the complete message
A simple solution is to write into files instead of standard output, and specifically, separate file for each thread. That way no locking or any other synchronization is needed. The files can later be merged if lines have parseable format.
Another solution is to write logs asynchronously from a single thread, and initially store the messages in a thread safe (possibly lock free) queue.
Also, is there a way to automatically add an std::endl for the last << call?
Unless I misunderstand, you can simply do stream << message << std::endl.
I think that you can simply use std::clog. It is thread safe and, in contrary of std::cout, designed to output instantly for logging.
From the reference page :
Unless sync_with_stdio(false) has been issued, it is safe to
concurrently access these objects from multiple threads for both
formatted and unformatted output.
I recommend you this Jason Turner's video about cout, clog and cerror.
The simplest approach is to return a temporary proxy from the first << - this can either log your stream for the duration (and unlock on destruction), or simply build a local ostringstream and flush it in a single call (again, on destruction).
Holding a lock while logging isn't great for performance (although it's better than your existing log method, which should use std::lock_guard for exception safety).
Building and discarding a temporary ostringstream is probably better, but if you care about performance you'll need to benchmark, and may well end up requiring something more elaborate (per-thread circular buffers, mmapped files or something).

Relying on deterministic destruction, avoiding destruction on return

I have been trying to rework my logging class. However, I'm facing a problem.
I want to expose this interface to users:
mylog() << "hello";
The idea is that mylog is an instance of Logger, which defines some useful characteristics for a defined log type. Its operator() function would return an instace of type LogStream. However, I would like to output the newline character automatically at the end, so I had the idea to do that in LogStream's destructor.
My current implementation looks like this (LogStream and Logger being largely dumbed down):
#include <iostream>
struct LogStream
{
~LogStream() { std::cout << '\n'; }
template<class T>
LogStream& operator<<(const T& t)
{
std::cout << t;
return *this;
}
};
struct Logger
{
LogStream operator()()
{
return LogStream{} << "message: ";
}
};
int main()
{
Logger log;
log() << "hello!";
}
Interstingly, I figured out with this piece of code that my previous implementation depended on RVO. The compiler was always performing copy-elision, so the destructor did behave the way I want. However, with this piece of code, the newline character is being printed twice, because the copy constructor is being called when the copy occurs in operator().
The problem disappears when I do not return the temporary instance, and instead put this in operator()'s body:
LogStream stream;
stream << "message: ";
return stream;
Now the RVO makes it work the way I want.
I later on = delete'd the copy constructors, because it made more sense anyway, which effectively causes the code to fail to compile.
What are my options to provide the interface I want, without using the hacky solution to rely on RVO?
Add a constructor to LogStream that takes a char const *.
LogStream(char const* c) { std::cout << c; }
Then, instead of creating a temporary LogStream within operator(), use list-initialization to initialize the return value itself.
LogStream operator()()
{
return {"message: "};
}
The temporary is thus avoided along with the extra new line.
Live demo (note that even using -fno-elide-constructors to disable copy elision doesn't result in the extra newline).

C++ Best approach to filtering bytes in a stream

I'm learning c++ (coming from a C and Java university coursework) and today I want to write a class that filters the bytes taken from a generic stream and writes its output to another stream.
To be coincise, let's say I want to make a class that base64-encodes the input and writes the output to stdout.
In bash I would write:
echo "some input data" | base64
In C++ i want to implement a class MyB64Encoder that would behave like this:
std::cout << myB64EncoderObject << "some input data";
//Alternatively, is it possible to make it like this?
std::cout << MyB64Encoder << "some input data";
The thing is, the myB64EncoderObject has, of course, to maintain an internal state and an internal buffer. To prevent blocking and excessive memory usage, it must be able to read and process small chunks of data and output each one of them immediately after it has been processed.
There are a few more things to take care of:
The object must wait for the output stream to be able to receive data
The object must throw an error if there is no stream reading from it (kinda like a broken pipe?)
What would be the best approach to a problem like this, in terms of efficiency? How would I implement it in modern C++1x?
The existing things that behave like this:
std::cout << myB64EncoderObject << "some input data";
are I/O manipulators (eg. std::boolalpha, std::hex, ...). However, these just set flags on the stream that it already knows how to interpret.
If you want to keep that syntax, you'll need to something more complex, namely an intermediate wrapper:
class B64Wrapper {
std::ostream &os_;
B64Encoder &enc_; // only if your encoder is really stateful
public:
B64Wrapper() = delete;
B64Wrapper(B64Wrapper&&) = default;
B64Wrapper(B64Wrapper const&) = default;
B64Wrapper(std::ostream &os, B64Encoder &enc) : os_(os), enc_(enc) {}
template <typename T>
B64Wrapper& operator<< (B64Wrapper &self, T val) {
self.enc_.encode(os_, val);
return self;
}
};
B64Wrapper operator<< (std::ostream &os, B64Encoder &enc) {
return B64Wrapper(os, enc);
}
(note you still need to write the B64Encoder::encode(std::ostream &, T value) method).
If your encoder isn't really stateful, you don't need a reference to it, and declare B64Encoder as an empty tag type with a global instance to get the same effect - in that case it only exists to select the operator<< overload.
The other approach is to write a std::basic_streambuf implementation which encodes the input to sputc/sputn/xsputn. It can forward everything else to a wrapped streambuf or to the base class, depending on what you inherit from.
You can do something like this:
class MyEncoder
{
public:
private:
std::ostream* os = nullptr;
// This overload deals with:
// std::cout << myEncoder ...
friend MyEncoder& operator<<(std::ostream& os, MyEncoder& me)
{
// grab a reference to the target output stream
me.os = &os;
return me;
}
// This overload deals with:
// std::cout << MyEncoder() ...
friend MyEncoder& operator<<(std::ostream& os, MyEncoder&& me)
{
// the temporary is currently bound to the l-value parameter me
// so we can just pass this call on to the previous overload
return os << me;
}
// This overload deals with:
// myEncoder << <anything else>
template<typename T>
friend MyEncoder& operator<<(MyEncoder& me, T const& v)
{
// only encode if there is an output stream to send the data to
// this will only be set if one of the above overloads was called
if(!me.os)
throw std::runtime_error("no stream to receive encoded data");
// do your encoding here
(*me.os) << "{encoded: " << v << "}";
return me;
}
};
Basically to achieve this:
std::cout << MyEncoder() << "some data: " << 45;
// ^ calls operator<<(MyEncoder&, 45)
// ^ calls operator<<(MyEncoder&, "some data: ")
// ^ calls operator<<(std::cout, MyEncoder())
The calls go left to right.
It may seem a little involved but it is basically covering 3 different call possibilities.
MyEncoder encoder;
std::cout << encoder; // MyEncoder& object
std::cout << MyEncoder(); // (temporary) MyEncoder&& object
encoder << "anything else" // A MyEncoder& receiving any other object
The first 2 operators are overloaded to set the internal std::ostream* and the third operator is overloaded to do the actual encoding.

How to detect if a ptr is still referencing a valid reference after that reference goes out of scope

I am toying around with streams for a bit and can't get my head around the following.
Here we have a basic ostream ptr that is set to different output streams, whether it is cout, cerr or a file.
// ostream ptr
std::ostream* outstream;
// set output ostream
void setOutput(std::ostream & os)
{
outstream = &os;
}
// write message to ostream
void writeData(const std::string & msg)
{
*outstream << msg << '\n';
}
int main (int argc, char * const argv[])
{
// init to std out
setOutput(std::cout);
writeData("message to cout");
setOutput(std::cerr);
writeData("message to cerr");
std::ofstream fileout("test.txt", std::ofstream::out | std::ofstream::app);
setOutput(fileout);
writeData("message to file");
//fileout.close();
setOutput(std::cout);
writeData("message2 to cout");
return 0;
}
The above works perfectly and shows the strength of the c++ iostream implementation. Perfect.
However, since the setOutput is set by reference the referenced object has to stay in scope. This is where the issue emerges. I want to figure out a way to default the output to std::cout if the ofstream or any other ostream is invalidated. That is, referenced object is or went out of scope.
For example:
// write message to ostream
void writeData(const std::string & msg)
{
if (/*stream or memory is invalid*/)
setOutput(std::cout);
*outstream << msg << '\n';
}
// local fileout goes out of scope
void foo()
{
std::ofstream fileout("test.txt", std::ofstream::out | std::ofstream::app);
setOutput(fileout);
writeData("message to file");
}
int main (int argc, char * const argv[])
{
setOutput(std::cout);
writeData("message to cout");
foo();
/* problem the local fileout is no longer referenced by the ostream ptr*/
/* the following should be redirected to std::cout cuz of default*/
writeData("message2 to cout");
return 0;
}
The above is fine until the foo() returns to the main function. There it goes horrible wrong because the locally defined ofstream is not reachable anymore.
Obviously this is not advisable and the user should realise this. However I want to wrap all this in a logging class and thus keep the state of the object valid even thought this misuse might happen. It will cause an invalidate access violation which can be hard to find.
Concrete question. Is there any way to figure out whether an ostream ptr or any ptr for that matter is still referencing a valid object or memory location?
ps: I could use heap memory and do something with smart pointers but frankly I'd want to keep it like this if possible
Concrete question. Is there any way to figure out whether an ostream ptr or any ptr for that matter is still referencing a valid object or memory location?
No. There is no way to figure that out with raw pointers. Not in standard c++ at least.
You will need to guarantee that the pointed object stays alive as long as it's pointed to.
A common pattern that is used to provide that guarantee is RAII, as detailed in other answers. Another approach to guaranteeing validity of of a pointer is to use a smart pointer instead of a raw one. However, those are not compatible with automatic variables.
It would be OK to keep pointing to dead objects as long as you could guarantee that the pointer is not dereferenced. Which is often difficult to guarantee, because, as already stated, there is no way to test whether the pointed object exists.
This sounds like a great use case for RAII.
Write a class that takes a filename and a std::ostream** as parameters to its constructor. In the constructor of the said class, construct the ofstream (as a member), and set the pointer to the ofstream. In the destructor, revert to stdout.
Then, replace the first two lines of the following function with a declaration of the new class.
void foo()
{
std::ofstream fileout("test.txt", std::ofstream::out | std::ofstream::app);
setOutput(fileout);
writeData("message to file");
}
You should use RAII to force the stream to be set correctly and then set back to std::cout if the object is destroyed.
class OutputStream
{
protected:
static std::ostream*& internalGlobalStateOfOutputStream()
{
static std::ostream* out = &std::cout;
return out;
}
public:
static std::ostream& getOutputStream()
{
return *internalGlobalStateOfOutputStream();
}
};
template<typename T>
class OutputStreamOwner: public OutputStream
{
T ownedStream;
public:
OutputStreamOwner(T&& obj)
: ownedStream(std::move(obj))
{
internalGlobalStateOfOutputStream() = &ownedStream;
}
template<typename... Args>
OutputStreamOwner(Args... args)
: ownedStream(args...)
{
internalGlobalStateOfOutputStream() = &ownedStream;
}
~OutputStreamOwner()
{
internalGlobalStateOfOutputStream() = & std::cout;
}
// Delete copy
OutputStreamOwner(OutputStreamOwner const&) = delete;
OutputStreamOwner& operator(OutputStreamOwner const&) = delete;
};
The usage is:
void foo()
{
OutputStreamOwner<std::ofstream> output("test.txt", std::ofstream::out | std::ofstream::app);
writeData("message to file");
}
A possible approach is to create a RAII class that wraps the stream before passing it into setOutput. This class should be designed to work like shared_ptr such that it maintains a shared ref count. writeData then checks to see if it has the only remaining reference and if so then destroys the ostream and defaults to cout.
You could avoid these complications altogether with a function that takes the stream as input.
void writeData(std::ostream& os, const std::string & msg)
{
os << msg << '\n';
}
You can further refine it by returning the stream, to allow one to chain calls to it:
std::ostream& os writeLine(std::ostream& os, const std::string & msg)
{
os << msg << '\n';
return os;
}
// declare stream
stream << writeLine(stream, "Foo") << writeLine(stream, "Bar");
In fact this function is nicer and easier to maintain, as you don't have to remember which stream is set at any given time. For large programs, this is an important quality.
Concrete question. Is there any way to figure out whether an ostream
ptr or any ptr for that matter is still referencing a valid object or
memory location?
ps: I could use heap memory and do something with smart pointers but
frankly I'd want to keep it like this if possible
No, there is no standard way to test if a raw pointer or reference is still referring to a valid object.
RAII is the standard C++ solution to this type of problem so you should be looking at smart pointers, in my opinion. I am not aware of any library provided smart pointer that would solve this particular problem but an RAII solution based on shared ownership seems the best solution here.

Two Phase Lookup operator << issue?

I'm trying to port my own code from VS2012 to g++4.8.
I'm getting this compliation error:
AllocationManager.cpp: In member function ‘void AllocationManager::printMemoryLeaks()’:
TRLogger.h:247:42: error: ‘streamAggrator’ was not declared in this scope
#define TRLOG_INFO streamAggrator(logINFO) << PACKET_DESCRIPTION << __FUNCTION__ << ":" << __LINE__ << ": "
^
AllocationManager.cpp:39:2: note: in expansion of macro ‘TRLOG_INFO’
TRLOG_INFO << "sdfs\n";
Where printMemoryLeaks is a dummy function (AllocationManager is not templated):
void AllocationManager::printMemoryLeaks(void)
{
TRLOG_INFO << "sdfs\n";
}
In the file TRLogger.h:
enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};
class streamAggrator
{
public:
streamAggrator(TLogLevel logLevel);
/* private: */
FILELog fLog;
WarnLog wlog;
std::ostringstream& s1;
std::ostringstream& s2;
};
template<typename T>
streamAggrator& operator<<(streamAggrator& agg, const T& obj)
{
agg.s1 << obj;
agg.s2 << obj;
agg.s2.flush();
return agg;
}
....
#define TRLOG_INFO streamAggrator(logINFO) << PACKET_DESCRIPTION << __FUNCTION__ << ":" << __LINE__ << ": "
How can I solve this function - I didn't find any place that I can use this or using to help the compiler.
Thanks,
Guy
Your immediate problem is that you try to pass a temporary streamAggrator object to a function which takes a streamAggrator by non-const reference. You can't bind temporary object to non-const references. The work-around for this problem is to make the output operator member of your streamAggrator: while you cannot bind a temporary to a non-const reference, you can call non-const member functions. Note that you'll also get problems with maniputors like std::flush (the issue there is that these are templates themselves and you actually need to a concrete operator to call them with to have the compiler deduce their template arguments).
Clearly, I would solve the problem properly, i.e., instead of trying to dig about an attempt to a solution which doesn't create a stream, I would create a std::streambuf do do the actual work. Your examples doesn't do anything useful, i.e., I can't really tell what you are trying to do but the code looks remarkably like trying to do something like teestream: write once but send the output to multiple destintations. I have posted corresponding stream buffers quite a few times in the post (mostly on Usenet, though, but I think, at least, once on Stackoverflow, too).
Although I don't know how to get rid of the macro to fill in the __FILE__ and the __LINE__, the actual stream formatting should probably use a stream buffer:
struct teebuf: std::streambuf {
private:
std::streambuf* sb1;
std::streambuf* sb2;
public:
teebuf(std::streambuf* sb1, std::streambuf* sb2): sb1(sb1), sb2(sb2) {}
int overflow(int c) {
this->sb1->sputc(c);
this->sb2->sputc(c);
return std::char_traits<char>::not_eof(c);
}
int sync() {
this->sb1->pubsync();
this->sb2->pubsync();
}
};
class logstream
: std::ostream {
std::ofstream out;
teebuf sbuf;
public:
logstream()
: out("file.log")
, sbuf(out.rdbuf(), std::clog.rdbuf()) {
this->init(&this->sbuf);
}
logstream(logstream&& other)
: out(std::move(other.out))
, sbuf(std::move(other.sbuf)) {
this->init(&this->sbuf);
};
I think you can return the log stream. I don't know what your logging level is meant to do but I guess its processing was removed while preparing the question: it is probably necessary to change the implementation to take the logging level suitably into account.