Commit 2c88ca44 by Carwyn

Improved: 日志模块重新实现

parent db092a87
...@@ -23,11 +23,13 @@ ...@@ -23,11 +23,13 @@
#include "fmp_logger_p.h" #include "fmp_logger_p.h"
FMPLogger::FMPLogger(ctkPluginContext *context) FMPLogger::FMPLogger(ctkPluginContext *context)
: d_ptr(new FMPLoggerPrivate(this)), : QObject(),
_inited(false), d_ptr(new FMPLoggerPrivate(this, context)),
_ctx(context) _max_size(d_ptr->GetMaxFilesize()),
_file(0),
_level(LOG_INFO)
{ {
Init(FMPProps()); StartService(FMPProps());
} }
FMPLogger::~FMPLogger() FMPLogger::~FMPLogger()
...@@ -35,41 +37,57 @@ FMPLogger::~FMPLogger() ...@@ -35,41 +37,57 @@ FMPLogger::~FMPLogger()
delete d_ptr; delete d_ptr;
} }
int FMPLogger::Init(const FMPProps &props) int FMPLogger::StartService(const FMPProps &props)
{ {
if (_inited) return FMP_SUCCESS;
Q_D(FMPLogger); Q_D(FMPLogger);
return d->Init(); return d->Init();
} }
int FMPLogger::Uninit() int FMPLogger::StopService()
{ {
if (!_inited) return FMP_SUCCESS;
Q_D(FMPLogger); Q_D(FMPLogger);
return d->Uninit(); return d->Uninit();
} }
int FMPLogger::GetMaxFilesize() void FMPLogger::Log(short level, const QString &msg, const char* file, const char* func, int line)
{ {
Q_D(FMPLogger); Q_D(FMPLogger);
return d->GetMaxFilesize(); d->Log(level, msg, file, func, line);
} }
void FMPLogger::SetMaxFilesize(quint64) uint FMPLogger::GetMaxFilesize() const
{ {
return _max_size;
} }
QString FMPLogger::GetFilename() void FMPLogger::SetMaxFilesize(uint sz)
{ {
return ""; Q_D(FMPLogger);
d->SetMaxFilesize(sz);
} }
FMPLogStream FMPLogger::Log(int level) QString FMPLogger::GetFilename() const
{
return _file->fileName();
}
QIODevice *FMPLogger::GetIODevice()
{ {
Q_D(FMPLogger); Q_D(FMPLogger);
return d->Log(level); d->_KeepFileSize();
return _file;
} }
short FMPLogger::GetLogLevel() const
{
return _level;
}
void FMPLogger::SetLogLevel(short level)
{
Q_D(FMPLogger);
d->SetLogLevel(level);
}
...@@ -17,27 +17,28 @@ class FMPLogger : public QObject, public FMPLoggerInterface ...@@ -17,27 +17,28 @@ class FMPLogger : public QObject, public FMPLoggerInterface
Q_INTERFACES(FMPLoggerInterface) Q_INTERFACES(FMPLoggerInterface)
Q_DECLARE_PRIVATE(FMPLogger) Q_DECLARE_PRIVATE(FMPLogger)
public: public:
explicit FMPLogger(ctkPluginContext *context); explicit FMPLogger(ctkPluginContext *context);
~FMPLogger(); ~FMPLogger();
int Init(const FMPProps &props); //! BaseInterface
int Uninit(); int StartService(const FMPProps &props);
int Upgrade() { return 0; } int StopService();
int Downgrade() { return 0; }
public slots:
void OnUpgraded() {}
public:
int GetMaxFilesize();
void SetMaxFilesize(quint64);
QString GetFilename();
FMPLogStream Log(int level = 0); //! LogInterface
void Log(short level, const QString &msg, const char* file, const char* func, int line);
short GetLogLevel() const;
void SetLogLevel(short level);
uint GetMaxFilesize() const;
void SetMaxFilesize(uint sz);
QString GetFilename() const;
QIODevice* GetIODevice();
private: private:
FMPLoggerPrivate *d_ptr; FMPLoggerPrivate *d_ptr;
bool _inited; short _level;
ctkPluginContext *_ctx; uint _max_size;
QFile *_file;
}; };
#endif // CTKLOGQDEBUG_P_H #endif // CTKLOGQDEBUG_P_H
...@@ -7,34 +7,72 @@ ...@@ -7,34 +7,72 @@
class FMPLoggerInterface : public FMPluginInterface class FMPLoggerInterface : public FMPluginInterface
{ {
public: public:
enum { LOG_ERROR = 1, LOG_WARNING, LOG_INFO, LOG_DEBUG };
/**
* @brief Log
* 函数方式记录日志
* @param level
* @param file
* @param func
* @param line
*/
virtual void Log(short level, const QString &msg, const char* file, const char* func, int line) = 0;
/**
* @brief GetLogLevel
* 获取当前日志记录级别
* @return
*/
virtual short GetLogLevel() const = 0;
/**
* @brief SetLogLevel
* 设置当前日志级别
* @param level
*/
virtual void SetLogLevel(short level) = 0;
/** /**
* @brief GetMaxFilesize * @brief GetMaxFilesize
* 获取日志文件最大容量(MB) * 获取日志文件最大容量(MB)
* @return 0 默认大小 n MB * @return 0 默认大小 n MB
*/ */
virtual int GetMaxFilesize() = 0; virtual uint GetMaxFilesize() const = 0;
/** /**
* @brief SetMaxFilesize * @brief SetMaxFilesize
* 设置日志文件最大容量(MB) * 设置日志文件最大容量(MB)
*/ */
virtual void SetMaxFilesize(quint64) = 0; virtual void SetMaxFilesize(uint) = 0;
/** /**
* @brief GetFilename * @brief GetFilename
* 获取当前日志文件路径 * 获取当前日志文件路径
* @return 文件路径 * @return 文件路径
*/ */
virtual QString GetFilename() = 0; virtual QString GetFilename() const = 0;
virtual FMPLogStream Log(int level = 0) = 0; /**
* @brief GetIODevice
* 获取文件输出设备指针(Stream使用)
* @return QIODevice*
*/
virtual QIODevice* GetIODevice() = 0;
}; };
Q_DECLARE_INTERFACE(FMPLoggerInterface, "fmp.logger") Q_DECLARE_INTERFACE(FMPLoggerInterface, "FMPLoggerInterface")
//! 快速日志记录宏定义
#define FMP_LOG(lvl, log) ((log && log->GetLogLevel() >= lvl) ? \
FMPLogStream(lvl, __FILE__, __FUNCTION__, __LINE__, log->GetIODevice()) : \
FMPNullLogStream(lvl, __FILE__, __FUNCTION__, __LINE__))
#define FMP_DEBUG(log) FMP_LOG(FMPLoggerInterface::LOG_DEBUG, log)
#define FMP_INFO(log) FMP_LOG(FMPLoggerInterface::LOG_INFO, log)
#define FMP_WARN(log) FMP_LOG(FMPLoggerInterface::LOG_WARNING, log)
#define FMP_ERROR(log) FMP_LOG(FMPLoggerInterface::LOG_ERROR, log)
#define FMPINFO(p) p->Log(FMPLogStream::INFO)
#define FMPWARNING(p) p->Log(FMPLogStream::WARNING)
#define FMPERROR(p) p->Log(FMPLogStream::ERROR)
#define FMPCRITICAL(p) p->Log(FMPLogStream::CRITICAL)
#define FMPDBG(p) p->Log(FMPLogStream::DEBUG)
#endif // FMP_LOGGER_I_H #endif // FMP_LOGGER_I_H
...@@ -5,54 +5,128 @@ ...@@ -5,54 +5,128 @@
#include <ctkPluginContext.h> #include <ctkPluginContext.h>
#include <ctkServiceReference.h> #include <ctkServiceReference.h>
FMPLoggerPrivate::FMPLoggerPrivate(FMPLogger *q) FMPLoggerPrivate::FMPLoggerPrivate(FMPLogger *q, ctkPluginContext *ctx)
: q_ptr(q) : q_ptr(q),
_ctx(ctx),
_inited(false)
{ {
_lvlmap[FMPLogger::LOG_DEBUG] = "debug";
_lvlmap[FMPLogger::LOG_INFO] = "info";
_lvlmap[FMPLogger::LOG_WARNING] = "warn";
_lvlmap[FMPLogger::LOG_ERROR] = "err";
} }
int FMPLoggerPrivate::Init() int FMPLoggerPrivate::Init()
{ {
if (_inited) return FMP_SUCCESS;
Q_Q(FMPLogger); Q_Q(FMPLogger);
QString filename = _NewFileName(); QString filename = _NewFileName();
_file.setFileName(filename); q->_file = new QFile(filename);
_file.open(QFile::WriteOnly); q->_file->open(QFile::WriteOnly);
q->_inited = true; _inited = true;
return FMP_SUCCESS; return FMP_SUCCESS;
} }
int FMPLoggerPrivate::Uninit() int FMPLoggerPrivate::Uninit()
{ {
if (!_inited) return FMP_SUCCESS;
Q_Q(FMPLogger); Q_Q(FMPLogger);
//! Clean up //! Clean up
_file.close(); q->_file->close();
q->_inited = false; _inited = false;
delete q->_file;
q->_file = 0;
return FMP_SUCCESS; return FMP_SUCCESS;
} }
int FMPLoggerPrivate::GetMaxFilesize() short FMPLoggerPrivate::GetLogLevel()
{
return _GetValue(FMP_INIKEY_LOGLEVEL, FMPLogger::LOG_INFO).toInt();
}
void FMPLoggerPrivate::SetLogLevel(short level)
{
if (_SetValue(FMP_INIKEY_LOGLEVEL, level)) {
Q_Q(FMPLogger);
q->_level = level;
}
}
uint FMPLoggerPrivate::GetMaxFilesize()
{
return _GetValue(FMP_INIKEY_LOGSIZE, 2).toUInt();
}
void FMPLoggerPrivate::SetMaxFilesize(uint sz)
{
if (_SetValue(FMP_INIKEY_LOGSIZE, sz)) {
Q_Q(FMPLogger);
q->_max_size = sz;
}
}
void FMPLoggerPrivate::Log(short level, const QString &msg, const char* file, const char* func, int line)
{ {
Q_Q(FMPLogger); Q_Q(FMPLogger);
ctkServiceReference setting_ref = CtxServiceRef(q->_ctx, FMPSettings); if (level > q->_level) {
if (!setting_ref.getPlugin().isNull()) { if (q->_file->size() >= (q->_max_size * 1024 * 1024)) {
FMPSettingsInterface *sets = qobject_cast<FMPSettingsInterface*>(q->_ctx->getService(setting_ref)); q->_file->close();
q->_file->setFileName(_NewFileName());
q->_file->open(QFile::WriteOnly);
}
FMPLogStream(level, file, func, line, q->_file) << msg;
}
else {
FMPNullLogStream(level, file, func, line) << msg;
}
}
QString FMPLoggerPrivate::_NewFileName()
{
QString file_time = QDateTime::currentDateTime().toString("yyMMddhhmmss");
Q_Q(FMPLogger);
return qApp->applicationFilePath().replace(".exe", "_" + _lvlmap[q->_level] + "_" + file_time + ".log");
}
bool FMPLoggerPrivate::_SetValue(const QString &key, QVariant v)
{
ctkServiceReference setting_ref = _ctx->getServiceReference<FMPSettingsInterface>();
if (setting_ref) {
FMPSettingsInterface *sets = _ctx->getService<FMPSettingsInterface>(setting_ref);
if (sets) { if (sets) {
return sets->GetInt(FMP_INIKEY_LOGSIZE); sets->SetValue(key, v);
return true;
} }
} }
return 0;
return false;
} }
FMPLogStream FMPLoggerPrivate::Log(int level) QVariant FMPLoggerPrivate::_GetValue(const QString &key, QVariant default_val)
{ {
return FMPLogStream(level, &_file); ctkServiceReference setting_ref = _ctx->getServiceReference<FMPSettingsInterface>();
if (setting_ref) {
FMPSettingsInterface *sets = _ctx->getService<FMPSettingsInterface>(setting_ref);
if (sets) {
return sets->GetValue(key);
}
}
return default_val;
} }
QString FMPLoggerPrivate::_NewFileName() void FMPLoggerPrivate::_KeepFileSize()
{ {
QString file_time = QDateTime::currentDateTime().toString("yyMMddhhmmss"); Q_Q(FMPLogger);
return qApp->applicationFilePath().replace(".exe", "_" + file_time + ".log"); if (q->_file->size() >= (q->_max_size * 1024 * 1024)) {
q->_file->close();
q->_file->setFileName(_NewFileName());
q->_file->open(QFile::WriteOnly);
}
} }
...@@ -7,20 +7,27 @@ class FMPLoggerPrivate ...@@ -7,20 +7,27 @@ class FMPLoggerPrivate
{ {
Q_DECLARE_PUBLIC(FMPLogger) Q_DECLARE_PUBLIC(FMPLogger)
public: public:
explicit FMPLoggerPrivate(FMPLogger *q); explicit FMPLoggerPrivate(FMPLogger *q, ctkPluginContext *ctx);
int Init(); int Init();
int Uninit(); int Uninit();
int GetMaxFilesize(); short GetLogLevel();
FMPLogStream Log(int level); void SetLogLevel(short level);
uint GetMaxFilesize();
void SetMaxFilesize(uint sz);
void Log(short level, const QString &msg, const char* file, const char* func, int line);
private: protected:
QString _NewFileName(); QString _NewFileName();
bool _SetValue(const QString &key, QVariant v);
QVariant _GetValue(const QString &key, QVariant default_val = 0);
void _KeepFileSize();
public: public:
FMPLogger *q_ptr; bool _inited;
private: FMPLogger *q_ptr;
int _level; ctkPluginContext *_ctx;
QFile _file; QMap<short, QString> _lvlmap;
}; };
#endif // FMP_LOGGER_P_H #endif // FMP_LOGGER_P_H
...@@ -8,37 +8,68 @@ class FMPLogStream : public QDebug ...@@ -8,37 +8,68 @@ class FMPLogStream : public QDebug
{ {
public: public:
enum { enum {
INFO = 0, WARNING, ERROR, CRITICAL, DEBUG ERROR = 1, WARNING, INFO, DEBUG
}; };
explicit FMPLogStream(int level, QIODevice *d = 0) explicit FMPLogStream(short level, const char* file, const char* func, int line, QIODevice* d = 0)
: QDebug(d), : QDebug(d),
_level(level) _level(level),
_file(file),
_func(func),
_line(line),
_device(d)
{ {
_lvmap[INFO] = "[INFO]";
_lvmap[WARNING] = "[WARNING]";
_lvmap[ERROR] = "[ERROR]"; _lvmap[ERROR] = "[ERROR]";
_lvmap[CRITICAL] = "[CRITICAL]"; _lvmap[WARNING] = "[WARNING]";
_lvmap[INFO] = "[INFO]";
_lvmap[DEBUG] = "[DEBUG]"; _lvmap[DEBUG] = "[DEBUG]";
} }
~FMPLogStream() ~FMPLogStream()
{ {
QDebug::operator <<(endl); if (this->_device) {
QDebug::operator <<(endl);
}
} }
template <typename T> template <typename T>
QDebug & operator<<(const T& t) QDebug & operator<<(const T& t)
{ {
QDebug & stream = *(this); QDebug & stream = *(this);
QString s = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz").append(_lvmap[_level]); if (!_device) {
stream.noquote() << s << t; stream = qDebug();
}
QString extra;
if (_level != INFO) {
QString filename(_file);
filename = filename.section("\\", -1);
filename = filename.section("/", -1);
extra += QString("%1(%2)").arg(filename).arg(QString::number(_line));
extra += QString("%1:").arg(_func);
}
QString s = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
s.append(_lvmap[_level]);
stream.noquote() << s << extra << t;
return *this; return stream;
} }
private: protected:
int _level; int _level;
QMap<int, QString> _lvmap; QMap<int, QString> _lvmap;
const char * _file;
const char * _func;
int _line;
QIODevice* _device;
};
class FMPNullLogStream : public FMPLogStream
{
public:
explicit FMPNullLogStream(short level, const char* file, const char* func, int line)
: FMPLogStream(level, file, func, line)
{}
}; };
#endif // FMP_LOGSTREAM_H #endif // FMP_LOGSTREAM_H
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#define VER_MINOR 1 #define VER_MINOR 1
#define VER_REVISION 0 #define VER_REVISION 0
#define VER_BUILD 4 #define VER_BUILD 5
//! Convert version numbers to string //! Convert version numbers to string
#define _STR(S) #S #define _STR(S) #S
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment