X-Git-Url: https://vaikene.ee/gitweb/pswgen11.html?a=blobdiff_plain;ds=sidebyside;f=src%2Flibs%2FCommon%2Flogger.cpp;h=94d9fa9eb9e7ea70136ed359960376a9ce844c68;hb=HEAD;hp=c7a50ddbed3fe90f8bb4034efd01b5c808fcc2f5;hpb=be0e791df48f5a8c9bb4c16f65b62e41e1149552;p=evaf
diff --git a/src/libs/Common/logger.cpp b/src/libs/Common/logger.cpp
index c7a50dd..94d9fa9 100644
--- a/src/libs/Common/logger.cpp
+++ b/src/libs/Common/logger.cpp
@@ -3,7 +3,7 @@
* @brief iLogger interface implementation
* @author Enar Vaikene
*
- * Copyright (c) 2011 Enar Vaikene
+ * Copyright (c) 2011-2019 Enar Vaikene
*
* This file is part of the eVaf C++ cross-platform application development framework.
*
@@ -20,6 +20,9 @@
#include "logger.h"
#include "iregistry.h"
#include "iapp.h"
+#include "iconfig.h"
+#include "globals.h"
+#include "inifile.h"
#include "version.h"
#include
@@ -37,9 +40,9 @@
//-------------------------------------------------------------------
-void eVaf::Common::Internal::defFatalMsgHandler(QString const & msg, QString const & source, QString const & where)
+[[noreturn]] void eVaf::Common::Internal::defFatalMsgHandler(QString const & msg, QString const & source, QString const & where)
{
- Q_UNUSED(source);
+ Q_UNUSED(source)
fprintf(stderr, "FATAL ERROR: %s (occurred in %s)\n", qPrintable(msg), qPrintable(where));
@@ -55,10 +58,18 @@ void eVaf::Common::Internal::defFatalMsgHandler(QString const & msg, QString con
using namespace eVaf::Common;
+namespace
+{
+ static Internal::Logger * singleton = nullptr;
+}
+
iLogger * iLogger::instance()
{
- static Internal::Logger singleton;
- return &singleton;
+ if (nullptr == singleton)
+ {
+ singleton = new Internal::Logger;
+ }
+ return singleton;
}
@@ -75,35 +86,61 @@ LoggerSource::LoggerSource()
LoggerSource::LoggerSource(LoggerSource const & o)
: QSharedData()
+ , name(o.name)
, severity(o.severity)
+ , fileName(o.fileName)
, maxSize(o.maxSize)
, maxCount(o.maxCount)
{}
-void LoggerSource::init(QString const & source, QString const & logDir, QString const & etcDir)
+void LoggerSource::init(QString const & source)
{
- Q_UNUSED(etcDir);
-
- fileName = logDir + source + ".log";
+ name = source;
+ fileName = iApp::instance()->logDir() + source + ".log";
+
+ // Set default settings
+ severity = iLogger::Fatal;
+ maxSize = 100 * 1024;
+ maxCount = 3;
+
+ // Read settings from the 'logger.ini' file
+ QString confFileName = iApp::instance()->etcDir() + "logger.ini";
+ if (QFile::exists(confFileName)) {
+ IniFile ini(confFileName, QIODevice::ReadOnly);
+
+ // Default values for all sources
+ maxSize = 1024 * ini.getValue(".default/log_size", maxSize / 1024).toUInt();
+ maxCount = ini.getValue(".default/log_count", maxCount).toUInt();
+
+ // Default values for this source
+ maxSize = 1024 * ini.getValue(source.toLatin1() + "/log_size", maxSize / 1024).toUInt();
+ maxCount = ini.getValue(source.toLatin1() + "/log_count", maxCount).toUInt();
+ }
}
//-------------------------------------------------------------------
-/// Recursively renames backup files
-void renameBackupFile(QDir & dir, QString const & baseName, int idx)
+namespace
{
- QString f1 = QString("%1.%2").arg(baseName).arg(idx);
- QString f2 = QString("%1.%2").arg(baseName).arg(idx + 1);
+ /// Recursively renames backup files
+ void renameBackupFile(QDir & dir, QString const & baseName, int idx)
+ {
+ QString f1 = QString("%1.%2").arg(baseName).arg(idx);
+ QString f2 = QString("%1.%2").arg(baseName).arg(idx + 1);
- if (dir.exists(f2))
- renameBackupFile(dir, baseName, idx + 1);
+ if (dir.exists(f2))
+ renameBackupFile(dir, baseName, idx + 1);
- dir.rename(f1, f2);
+ dir.rename(f1, f2);
+ }
}
void LoggerWorker::writeToLogFile(LoggerSource const & src, QString const & msg)
{
+ //::printf("writeToLogFile(\'%s\', \'%s\') fileName = \'%s\'\n", qPrintable(src.name), qPrintable(msg), qPrintable(src.fileName));
+ if (src.fileName.isEmpty())
+ return;
QFile f(src.fileName);
QFile::OpenMode mode;
#ifdef Q_OS_LINUX
@@ -142,37 +179,48 @@ void LoggerWorker::writeToLogFile(LoggerSource const & src, QString const & msg)
//-------------------------------------------------------------------
+void Logger::destroyInstance()
+{
+ if (singleton != nullptr)
+ {
+ delete singleton;
+ singleton = nullptr;
+ }
+}
+
Logger::Logger()
: iLogger()
+ , mReady(false)
, mFatalMsgHandler(defFatalMsgHandler)
, mConsoleSeverity(iLogger::Fatal)
- , mDefaultSource("evaf")
- , mThread(0)
- , mWorker(0)
{
setObjectName(QString("%1-iLogger").arg(VER_MODULE_NAME_STR));
qRegisterMetaType("LoggerSource");
- write(Info, QString("%1 created").arg(objectName()), 0, printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__));
+ // Create the default source
+ mDefaultSource = new LoggerSource;
+ mDefaultSource->name = "common";
+
+ write(Info, QString("%1 created").arg(objectName()), QString(), printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__));
}
Logger::~Logger()
{
// Disconnect any potential receivers from this object
- disconnect(this, SIGNAL(loggerEvent(eVaf::Common::iLogger::Severity,QString,QString,QString)), 0, 0);
+ disconnect(this, SIGNAL(loggerEvent(Common::iLogger::Severity,QString,QString,QString)), nullptr, nullptr);
// Destroy the worker thread
if (mWorker) {
- delete mWorker;
+ mWorker.reset();
if (mThread) {
mThread->quit();
mThread->wait();
- delete mThread;
+ mThread.reset();
}
}
- write(Info, QString("%1 destroyed").arg(objectName()), 0, printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__));
+ write(Info, QString("%1 destroyed").arg(objectName()), QString(), printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__));
}
bool Logger::init()
@@ -183,31 +231,50 @@ bool Logger::init()
// Clear existing sources in case the application was restarted
mSources.clear();
+ // Set the default source name to the name of the application
+ setDefaultSource(iApp::instance()->name());
+
+ // Read configuration parameters from the application's INI file
+ QVariant v = iConfig::instance()->getValue(QString("%1/general/log_level").arg(iApp::instance()->name()), severity());
+ if (v.isValid())
+ setSeverity(iLogger::Severity(qBound(int(iLogger::None), v.toInt(), int(iLogger::Debug))));
+ v = iConfig::instance()->getValue(QString("%1/general/log_size").arg(iApp::instance()->name()), maxSize());
+ if (v.isValid())
+ setMaxSize(v.toUInt());
+ v = iConfig::instance()->getValue(QString("%1/general/log_cnt").arg(iApp::instance()->name()), maxCount());
+ if (v.isValid())
+ setMaxCount(v.toUInt());
+
// Destroy the previous worker thread
- if (mWorker) {
- delete mWorker;
- if (mThread) {
- mThread->quit();
- mThread->wait();
- delete mThread;
- }
+ if (mThread) {
+ mThread->quit();
+ mThread->wait();
}
// Create the worker thread
- mWorker = new LoggerWorker;
- mThread = new QThread;
- mWorker->moveToThread(mThread);
+ mWorker.reset(new LoggerWorker);
+ mThread.reset(new QThread);
+ mWorker->moveToThread(mThread.data());
mThread->start(QThread::IdlePriority);
- connect(this, SIGNAL(writeToLogFile(LoggerSource,QString)), mWorker, SLOT(writeToLogFile(LoggerSource,QString)), Qt::QueuedConnection);
+ connect(this, SIGNAL(writeToLogFile(LoggerSource,QString)), mWorker.data(), SLOT(writeToLogFile(LoggerSource,QString)), Qt::QueuedConnection);
- write(Info, QString("%1 initialized").arg(objectName()), 0, printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__));
+ mReady = true;
+
+ write(Info, QString("%1 initialized").arg(objectName()), QString(), printf("%s:%s:%d", __FILE__, __FUNCTION__, __LINE__));
return true;
}
+QString Logger::defaultSource() const
+{
+ return mDefaultSource->name;
+}
+
void Logger::setDefaultSource(QString const & source)
{
- mDefaultSource = source;
+ LoggerSource * src = getSource();
+ if (src && src->name != source)
+ getSource(QString())->init(source);
}
iLogger::Severity Logger::severity(QString const & source)
@@ -227,7 +294,7 @@ uint Logger::maxSize(QString const & source)
void Logger::setMaxSize(uint maxSize, QString const & source)
{
- getSource(source)->maxSize = maxSize;
+ getSource(source)->maxSize = maxSize * 1024;
}
uint Logger::maxCount(QString const & source)
@@ -262,46 +329,30 @@ void Logger::write(Severity severity, QString const & msg, QString const & sourc
return;
// Write to the log file
- LoggerSource * src = getSource(source);
- if (severity <= src->severity && src->severity != iLogger::None) {
- QString buf;
- QTextStream io(&buf);
+ if (mReady) {
+ LoggerSource * src = getSource(source);
+ if (severity <= src->severity && src->severity != iLogger::None) {
+ QString buf;
+ QTextStream io(&buf);
- // Date/time stamp
- io << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
+ // Date/time stamp
+ io << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
- // Severity
- io << " " << severityText[severity];
+ // Severity
+ io << " " << severityText[severity];
- // Message
- io << msg;
+ // Message
+ io << msg;
- // Location in the source file
- if (!where.isEmpty())
- io << " (occurred in " << where << ")";
+ // Location in the source file
+ if (!where.isEmpty())
+ io << " (occurred in " << where << ")";
- io << endl;
- io.flush();
+ io << endl;
+ io.flush();
- // If the worker is initialized, use the worker thread to do the job
- if (mWorker) {
emit writeToLogFile(*src, buf);
}
- // Otherwise we have to do it ourselves
- else {
- QFile f(src->fileName);
- QFile::OpenMode mode;
-#ifdef Q_OS_LINUX
- mode = QFile::Append | QFile::Text | QFile::Unbuffered;
-#else
- mode = QFile::Append | QFile::Text;
-#endif
-
- if (f.open(mode)) {
- f.write(buf.toLocal8Bit());
- f.close();
- }
- }
}
// Output to the console
@@ -309,25 +360,25 @@ void Logger::write(Severity severity, QString const & msg, QString const & sourc
FILE * f = (severity < iLogger::Info) ? stderr : stdout;
// Set text colors
-#ifdef Q_OS_LINUX
+#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
switch (severity) {
case iLogger::Info:
- fprintf(f, "\e[32m"); // Green
+ fprintf(f, "\033[32m"); // Green
break;
case iLogger::Warning:
- fprintf(f, "\e[1m"); // Bold
+ fprintf(f, "\033[1m"); // Bold
break;
case iLogger::Error:
- fprintf(f, "\e[31m"); // Red
+ fprintf(f, "\033[31m"); // Red
break;
case iLogger::Fatal:
- fprintf(f, "\e[31m\e[1m"); // Bold Red
+ fprintf(f, "\033[31m\033[1m"); // Bold Red
break;
default:
- fprintf(f, "\e[34m"); // Blue
+ fprintf(f, "\033[34m"); // Blue
break;
}
-#elif defined Q_OS_WIN32
+#elif defined(Q_OS_WIN32)
switch (severity) {
case iLogger::Info:
setColor(FOREGROUND_GREEN);
@@ -355,9 +406,9 @@ void Logger::write(Severity severity, QString const & msg, QString const & sourc
fprintf(f, "\t(occurred in %s)\n\n", qPrintable(where));
// Reset text colors
-#ifdef Q_OS_LINUX
- fputs("\e[0m", f);
-#elif defined Q_OS_WIN32
+#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
+ fputs("\033[0m", f);
+#elif defined(Q_OS_WIN32)
setColor(7);
#endif
@@ -378,17 +429,21 @@ QString Logger::printf(char const * const fmt, ...) const
#ifdef Q_OS_WIN32
char str[4096];
#else
- char * str = 0;
+ char * str = nullptr;
#endif
va_list ap;
#ifdef Q_OS_WIN32
va_start(ap, fmt);
+# ifdef Q_CC_GNU
+ vsnprintf(str, sizeof(str), fmt, ap);
+# else
_vsnprintf_s(str, sizeof(str), _TRUNCATE, fmt, ap);
+# endif
va_end(ap);
#else
::va_start(ap, fmt);
- if (::vasprintf(&str, fmt, ap)); // IF is needed to avoid the compiler warning
+ if (::vasprintf(&str, fmt, ap)) {} // IF is needed to avoid the compiler warning
::va_end(ap);
#endif
@@ -436,6 +491,9 @@ FatalMsgHandler Logger::installFatalMsgHandler(FatalMsgHandler newHandler)
LoggerSource * Logger::getSource(QString const & source)
{
+ if (source.isEmpty() || source == mDefaultSource->name)
+ return mDefaultSource.data();
+
QHash >::const_iterator it = mSources.constFind(source);
if (it != mSources.constEnd())
return it->data();
@@ -445,7 +503,7 @@ LoggerSource * Logger::getSource(QString const & source)
mSources.insert(source, src);
// Initialize the new source
- src->init(source.isEmpty() ? mDefaultSource : source, iApp::instance()->logDir(), iApp::instance()->etcDir());
+ src->init(source);
return src.data();
}