File commoncpp2-applog.patch of Package commoncpp2
--- src/applog.cpp.orig 2012-09-07 00:06:52.116623618 +0200
+++ src/applog.cpp 2012-09-07 00:06:56.294734349 +0200
@@ -38,6 +38,10 @@
#include <cc++/thread.h>
#include <cc++/slog.h>
#include <cc++/buffer.h>
+#ifndef WIN32
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
#include <string>
#include <iomanip>
#include <iostream>
@@ -115,6 +119,7 @@
string _nomeFile;
std::fstream _logfs;
bool _usePipe;
+ bool _closedByApplog;
protected:
// to dequeue log messages and write them to file if not log_directly
@@ -123,7 +128,8 @@
virtual void stopQueue(void);
virtual void onTimer(void);
virtual void final(void);
-
+ void _openFile();
+
public:
logger(const char* logFileName = NULL, bool usePipe = false);
virtual ~logger();
@@ -131,6 +137,9 @@
// To change log file name
void logFileName(const char* FileName, bool usePipe = false);
+ void openFile();
+ void closeFile();
+
};
@@ -281,35 +290,14 @@
}
// class logger
-logger::logger(const char* logFileName, bool usePipe) : ThreadQueue(NULL, 0, 0), _usePipe(usePipe)
+logger::logger(const char* logFileName, bool usePipe) : ThreadQueue(NULL, 0, 0), _usePipe(usePipe), _closedByApplog(false)
{
_nomeFile = "";
if (logFileName)
_nomeFile = logFileName;
- if (!_nomeFile.empty())
- {
- if (!_usePipe)
- {
- _logfs.open(_nomeFile.c_str(), std::ofstream::out | std::ofstream::app | std::ofstream::ate);
- }
-#ifndef WIN32
- else
- {
- // create pipe
- int err = mkfifo(_nomeFile.c_str(), S_IREAD | S_IWRITE);
- if (err == 0 || errno == EEXIST)
- {
- // and open it
- _logfs.open(_nomeFile.c_str(), std::fstream::in | std::fstream::out);
- }
- else
- THROW(AppLogException("Can't create pipe"));
- }
-#endif
- if (_logfs.fail())
- THROW(AppLogException("Can't open log file name"));
- }
+
+ openFile();
}
logger::~logger()
@@ -332,37 +320,73 @@
if (_logfs.is_open())
_logfs.close();
- if (!_nomeFile.empty())
+ openFile();
+}
+
+/// open also logger if applog->open() is invoked
+void logger::openFile()
+{
+ _closedByApplog=false;
+}
+
+///internal logger openFile needed to use pipe and avoid stream buffering in the case
+/// the consumer is not connected to pipe
+void logger::_openFile()
+{
+ if (!_closedByApplog && !_logfs.is_open())
{
- if (!_usePipe)
- {
- _logfs.open(_nomeFile.c_str(), std::ofstream::out | std::ofstream::app | std::ofstream::ate);
- }
-#ifndef WIN32
- else
+ if (!_nomeFile.empty())
{
- // create pipe
- int err = mkfifo(_nomeFile.c_str(), S_IREAD | S_IWRITE);
- if (err == 0 || errno == EEXIST)
+ _logfs.clear();
+ if (!_usePipe)
{
- // and open it
- _logfs.open(_nomeFile.c_str(), std::fstream::in | std::fstream::out);
+ _logfs.open(_nomeFile.c_str(), std::ofstream::out | std::ofstream::app | std::ofstream::ate);
}
+#ifndef WIN32
else
- THROW(AppLogException("Can't create pipe"));
- }
+ {
+ // create pipe
+ int err = mkfifo(_nomeFile.c_str(), S_IREAD | S_IWRITE);
+ if (err == 0 || errno == EEXIST)
+ {
+ // and open it
+ _logfs.open(_nomeFile.c_str(), std::fstream::in | std::fstream::out);
+ }
+ else
+ THROW(AppLogException("Can't create pipe"));
+ }
#endif
- if (_logfs.fail())
- THROW(AppLogException("Can't open log file name"));
+ if (_logfs.fail())
+ THROW(AppLogException("Can't open log file name"));
+ }
}
+}
+/// close also logger if applog->close() is invoked
+void logger::closeFile()
+{
+ _closedByApplog = true;
}
+
// writes into filename enqueued messages
void logger::runQueue(void * data)
{
char *str = (char *) data;
+ // if for some internal reasons file has been closed
+ // reopen it
+ try
+ {
+ _openFile();
+ }
+ catch (AppLogException e)
+ {
+ std::cerr << e.what() << std::endl;
+ slog.emerg("%s\n", e.what());
+ std::cerr.flush();
+ }
+
if (_logfs.is_open())
{
Thread::setCancel(cancelDisabled);
@@ -370,6 +394,14 @@
_logfs.flush();
Thread::setCancel(cancelImmediate);
}
+
+ //if we use a pipe to avoid increasing of stream buffer
+ // without a consumer, we open, use and close it
+ if ((_usePipe || _closedByApplog) && _logfs.is_open())
+ {
+ _logfs.flush();
+ _logfs.close();
+ }
}
void logger::startQueue()
@@ -541,7 +573,6 @@
#endif
if (!d->_logDirectly)
{
- d->_nomeFile = FileName;
if (d->_pLogger)
d->_pLogger->logFileName(FileName, d->_logPipe);
else
@@ -724,6 +755,11 @@
}
d->_lock.leaveMutex();
}
+ else
+ {
+ if (d->_pLogger)
+ d->_pLogger->closeFile();
+ }
}
void AppLog::open(const char *ident)
@@ -756,6 +792,11 @@
}
d->_lock.leaveMutex();
}
+ else
+ {
+ if (d->_pLogger)
+ d->_pLogger->openFile();
+ }
if (ident != NULL)
logIt->second._ident = ident;