mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 17:33:05 +00:00
Add logger
Change-Id: I4ae4e2d77d137646b312b2c6124dd6ab2653936e
This commit is contained in:
parent
d65a3bf904
commit
593b20d5c1
Notes:
Deepin Code Review
2016-06-14 07:19:47 +00:00
Verified+1: Anonymous Coward #1000004 Code-Review+2: <mr.asianwang@gmail.com> Submitted-by: <mr.asianwang@gmail.com> Submitted-at: Fri, 25 Sep 2015 19:57:55 +0800 Reviewed-on: https://cr.deepin.io/7406 Project: dde/dde-dock Branch: refs/heads/master
147
cutelogger/AbstractAppender.cpp
Normal file
147
cutelogger/AbstractAppender.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
// Local
|
||||
#include "AbstractAppender.h"
|
||||
|
||||
// Qt
|
||||
#include <QMutexLocker>
|
||||
|
||||
|
||||
/**
|
||||
* \class AbstractAppender
|
||||
*
|
||||
* \brief The AbstractAppender class provides an abstract base class for writing a log entries.
|
||||
*
|
||||
* The AbstractAppender class is the base interface class for all log appenders that could be used with Logger.
|
||||
*
|
||||
* AbstractAppender provides a common implementation for the thread safe, mutex-protected logging of application
|
||||
* messages, such as ConsoleAppender, FileAppender or something else. AbstractAppender is abstract and can not be
|
||||
* instantiated, but you can use any of its subclasses or create a custom log appender at your choice.
|
||||
*
|
||||
* Appenders are the logical devices that is aimed to be attached to Logger object by calling
|
||||
* Logger::registerAppender(). On each log record call from the application Logger object sequentially calls write()
|
||||
* function on all the appenders registered in it.
|
||||
*
|
||||
* You can subclass AbstractAppender to implement a logging target of any kind you like. It may be the external logging
|
||||
* subsystem (for example, syslog in *nix), XML file, SQL database entries, D-Bus messages or anything else you can
|
||||
* imagine.
|
||||
*
|
||||
* For the simple non-structured plain text logging (for example, to a plain text file or to the console output) you may
|
||||
* like to subclass the AbstractStringAppender instead of AbstractAppender, which will give you a more convinient way to
|
||||
* control the format of the log output.
|
||||
*
|
||||
* \sa AbstractStringAppender
|
||||
* \sa Logger::registerAppender()
|
||||
*/
|
||||
|
||||
|
||||
//! Constructs a AbstractAppender object.
|
||||
AbstractAppender::AbstractAppender()
|
||||
: m_detailsLevel(Logger::Debug)
|
||||
{}
|
||||
|
||||
|
||||
//! Destructs the AbstractAppender object.
|
||||
AbstractAppender::~AbstractAppender()
|
||||
{}
|
||||
|
||||
|
||||
//! Returns the current details level of appender.
|
||||
/**
|
||||
* Log records with a log level lower than a current detailsLevel() will be silently ignored by appender and would not
|
||||
* be sent to its append() function.
|
||||
*
|
||||
* It provides additional logging flexibility, allowing you to set the different severity levels for different types
|
||||
* of logs.
|
||||
*
|
||||
* \note This function is thread safe.
|
||||
*
|
||||
* \sa setDetailsLevel()
|
||||
* \sa Logger::LogLevel
|
||||
*/
|
||||
Logger::LogLevel AbstractAppender::detailsLevel() const
|
||||
{
|
||||
QMutexLocker locker(&m_detailsLevelMutex);
|
||||
return m_detailsLevel;
|
||||
}
|
||||
|
||||
|
||||
//! Sets the current details level of appender.
|
||||
/**
|
||||
* Default details level is Logger::Debug
|
||||
*
|
||||
* \note This function is thread safe.
|
||||
*
|
||||
* \sa detailsLevel()
|
||||
* \sa Logger::LogLevel
|
||||
*/
|
||||
void AbstractAppender::setDetailsLevel(Logger::LogLevel level)
|
||||
{
|
||||
QMutexLocker locker(&m_detailsLevelMutex);
|
||||
m_detailsLevel = level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Sets the current details level of appender
|
||||
/**
|
||||
* This function is provided for convenience, it behaves like an above function.
|
||||
*
|
||||
* \sa detailsLevel()
|
||||
* \sa Logger::LogLevel
|
||||
*/
|
||||
void AbstractAppender::setDetailsLevel(const QString& level)
|
||||
{
|
||||
setDetailsLevel(Logger::levelFromString(level));
|
||||
}
|
||||
|
||||
|
||||
//! Tries to write the log record to this logger
|
||||
/**
|
||||
* This is the function called by Logger object to write a log message to the appender.
|
||||
*
|
||||
* \note This function is thread safe.
|
||||
*
|
||||
* \sa Logger::write()
|
||||
* \sa detailsLevel()
|
||||
*/
|
||||
void AbstractAppender::write(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message)
|
||||
{
|
||||
if (logLevel >= detailsLevel())
|
||||
{
|
||||
QMutexLocker locker(&m_writeMutex);
|
||||
append(timeStamp, logLevel, file, line, function, category, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \fn virtual void AbstractAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file,
|
||||
* int line, const char* function, const QString& message)
|
||||
*
|
||||
* \brief Writes the log record to the logger instance
|
||||
*
|
||||
* This function is called every time when user tries to write a message to this AbstractAppender instance using
|
||||
* the write() function. Write function works as proxy and transfers only the messages with log level more or equal
|
||||
* to the current logLevel().
|
||||
*
|
||||
* Overload this function when you are implementing a custom appender.
|
||||
*
|
||||
* \note This function is not needed to be thread safe because it is never called directly by Logger object. The
|
||||
* write() function works as a proxy and protects this function from concurrent access.
|
||||
*
|
||||
* \sa Logger::write()
|
||||
*/
|
||||
|
49
cutelogger/AbstractAppender.h
Normal file
49
cutelogger/AbstractAppender.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
#ifndef ABSTRACTAPPENDER_H
|
||||
#define ABSTRACTAPPENDER_H
|
||||
|
||||
// Local
|
||||
#include "CuteLogger_global.h"
|
||||
#include <Logger.h>
|
||||
|
||||
// Qt
|
||||
#include <QMutex>
|
||||
|
||||
|
||||
class CUTELOGGERSHARED_EXPORT AbstractAppender
|
||||
{
|
||||
public:
|
||||
AbstractAppender();
|
||||
virtual ~AbstractAppender();
|
||||
|
||||
Logger::LogLevel detailsLevel() const;
|
||||
void setDetailsLevel(Logger::LogLevel level);
|
||||
void setDetailsLevel(const QString& level);
|
||||
|
||||
void write(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line, const char* function,
|
||||
const QString& category, const QString& message);
|
||||
|
||||
protected:
|
||||
virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message) = 0;
|
||||
|
||||
private:
|
||||
QMutex m_writeMutex;
|
||||
|
||||
Logger::LogLevel m_detailsLevel;
|
||||
mutable QMutex m_detailsLevelMutex;
|
||||
};
|
||||
|
||||
#endif // ABSTRACTAPPENDER_H
|
459
cutelogger/AbstractStringAppender.cpp
Normal file
459
cutelogger/AbstractStringAppender.cpp
Normal file
@ -0,0 +1,459 @@
|
||||
/*
|
||||
Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com) Nikolay Matyunin (matyunin.n at gmail dot com)
|
||||
|
||||
Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
// Local
|
||||
#include "AbstractStringAppender.h"
|
||||
|
||||
// Qt
|
||||
#include <QReadLocker>
|
||||
#include <QWriteLocker>
|
||||
#include <QDateTime>
|
||||
#include <QRegExp>
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
|
||||
|
||||
/**
|
||||
* \class AbstractStringAppender
|
||||
*
|
||||
* \brief The AbstractStringAppender class provides a convinient base for appenders working with plain text formatted
|
||||
* logs.
|
||||
*
|
||||
* AbstractSringAppender is the simple extension of the AbstractAppender class providing the convinient way to create
|
||||
* custom log appenders working with a plain text formatted log targets.
|
||||
*
|
||||
* It have the formattedString() protected function that formats the logging arguments according to a format set with
|
||||
* setFormat().
|
||||
*
|
||||
* This class can not be directly instantiated because it contains pure virtual function inherited from AbstractAppender
|
||||
* class.
|
||||
*
|
||||
* For more detailed description of customizing the log output format see the documentation on the setFormat() function.
|
||||
*/
|
||||
|
||||
|
||||
const char formattingMarker = '%';
|
||||
|
||||
|
||||
//! Constructs a new string appender object
|
||||
AbstractStringAppender::AbstractStringAppender()
|
||||
: m_format(QLatin1String("%{time}{yyyy-MM-ddTHH:mm:ss.zzz} [%{type:-7}] <%{function}> %{message}\n"))
|
||||
{}
|
||||
|
||||
|
||||
//! Returns the current log format string.
|
||||
/**
|
||||
* The default format is set to "%{time}{yyyy-MM-ddTHH:mm:ss.zzz} [%{type:-7}] <%{function}> %{message}\n". You can set a different log record
|
||||
* format using the setFormat() function.
|
||||
*
|
||||
* \sa setFormat(const QString&)
|
||||
*/
|
||||
QString AbstractStringAppender::format() const
|
||||
{
|
||||
QReadLocker locker(&m_formatLock);
|
||||
return m_format;
|
||||
}
|
||||
|
||||
|
||||
//! Sets the logging format for writing strings to the log target with this appender.
|
||||
/**
|
||||
* The string format seems to be very common to those developers who have used a standart sprintf function.
|
||||
*
|
||||
* Log output format is a simple QString with the special markers (starting with % sign) which will be replaced with
|
||||
* it's internal meaning when writing a log record.
|
||||
*
|
||||
* Controlling marker begins with the percent sign (%) which is followed by the command inside {} brackets
|
||||
* (the command describes, what will be put to log record instead of marker).
|
||||
* Optional field width argument may be specified right after the command (through the colon symbol before the closing bracket)
|
||||
* Some commands requires an additional formatting argument (in the second {} brackets).
|
||||
*
|
||||
* Field width argument works almost identically to the \c QString::arg() \c fieldWidth argument (and uses it
|
||||
* internally). For example, \c "%{type:-7}" will be replaced with the left padded debug level of the message
|
||||
* (\c "Debug ") or something. For the more detailed description of it you may consider to look to the Qt
|
||||
* Reference Documentation.
|
||||
*
|
||||
* Supported marker commands are:
|
||||
* \arg \c %{time} - timestamp. You may specify your custom timestamp format using the second {} brackets after the marker,
|
||||
* timestamp format here will be similiar to those used in QDateTime::toString() function. For example,
|
||||
* "%{time}{dd-MM-yyyy, HH:mm}" may be replaced with "17-12-2010, 20:17" depending on current date and time.
|
||||
* The default format used here is "HH:mm:ss.zzz".
|
||||
* \arg \c %{type} - Log level. Possible log levels are shown in the Logger::LogLevel enumerator.
|
||||
* \arg \c %{Type} - Uppercased log level.
|
||||
* \arg \c %{typeOne} - One letter log level.
|
||||
* \arg \c %{TypeOne} - One uppercase letter log level.
|
||||
* \arg \c %{File} - Full source file name (with path) of the file that requested log recording. Uses the \c __FILE__
|
||||
* preprocessor macro.
|
||||
* \arg \c %{file} - Short file name (with stripped path).
|
||||
* \arg \c %{line} - Line number in the source file. Uses the \c __LINE__ preprocessor macro.
|
||||
* \arg \c %{Function} - Name of function that called on of the LOG_* macros. Uses the \c Q_FUNC_INFO macro provided with
|
||||
* Qt.
|
||||
* \arg \c %{function} - Similiar to the %{Function}, but the function name is stripped using stripFunctionName
|
||||
* \arg \c %{message} - The log message sent by the caller.
|
||||
* \arg \c %{category} - The log category.
|
||||
* \arg \c %{appname} - Application name (returned by QCoreApplication::applicationName() function).
|
||||
* \arg \c %{pid} - Application pid (returned by QCoreApplication::applicationPid() function).
|
||||
* \arg \c %{threadid} - ID of current thread.
|
||||
* \arg \c %% - Convinient marker that is replaced with the single \c % mark.
|
||||
*
|
||||
* \note Format doesn't add \c '\\n' to the end of the format line. Please consider adding it manually.
|
||||
*
|
||||
* \sa format()
|
||||
* \sa stripFunctionName()
|
||||
* \sa Logger::LogLevel
|
||||
*/
|
||||
void AbstractStringAppender::setFormat(const QString& format)
|
||||
{
|
||||
QWriteLocker locker(&m_formatLock);
|
||||
m_format = format;
|
||||
}
|
||||
|
||||
|
||||
//! Strips the long function signature (as added by Q_FUNC_INFO macro)
|
||||
/**
|
||||
* The string processing drops the returning type, arguments and template parameters of function. It is definitely
|
||||
* useful for enchancing the log output readability.
|
||||
* \return stripped function name
|
||||
*/
|
||||
QString AbstractStringAppender::stripFunctionName(const char* name)
|
||||
{
|
||||
return QString::fromLatin1(qCleanupFuncinfo(name));
|
||||
}
|
||||
|
||||
|
||||
// The function was backported from Qt5 sources (qlogging.h)
|
||||
QByteArray AbstractStringAppender::qCleanupFuncinfo(const char* name)
|
||||
{
|
||||
QByteArray info(name);
|
||||
|
||||
// Strip the function info down to the base function name
|
||||
// note that this throws away the template definitions,
|
||||
// the parameter types (overloads) and any const/volatile qualifiers.
|
||||
if (info.isEmpty())
|
||||
return info;
|
||||
|
||||
int pos;
|
||||
|
||||
// skip trailing [with XXX] for templates (gcc)
|
||||
pos = info.size() - 1;
|
||||
if (info.endsWith(']')) {
|
||||
while (--pos) {
|
||||
if (info.at(pos) == '[')
|
||||
info.truncate(pos);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasLambda = false;
|
||||
QRegExp lambdaRegex("::<lambda\\(.*\\)>");
|
||||
int lambdaIndex = lambdaRegex.indexIn(QString::fromLatin1(info));
|
||||
if (lambdaIndex != -1)
|
||||
{
|
||||
hasLambda = true;
|
||||
info.remove(lambdaIndex, lambdaRegex.matchedLength());
|
||||
}
|
||||
|
||||
// operator names with '(', ')', '<', '>' in it
|
||||
static const char operator_call[] = "operator()";
|
||||
static const char operator_lessThan[] = "operator<";
|
||||
static const char operator_greaterThan[] = "operator>";
|
||||
static const char operator_lessThanEqual[] = "operator<=";
|
||||
static const char operator_greaterThanEqual[] = "operator>=";
|
||||
|
||||
// canonize operator names
|
||||
info.replace("operator ", "operator");
|
||||
|
||||
// remove argument list
|
||||
forever {
|
||||
int parencount = 0;
|
||||
pos = info.lastIndexOf(')');
|
||||
if (pos == -1) {
|
||||
// Don't know how to parse this function name
|
||||
return info;
|
||||
}
|
||||
|
||||
// find the beginning of the argument list
|
||||
--pos;
|
||||
++parencount;
|
||||
while (pos && parencount) {
|
||||
if (info.at(pos) == ')')
|
||||
++parencount;
|
||||
else if (info.at(pos) == '(')
|
||||
--parencount;
|
||||
--pos;
|
||||
}
|
||||
if (parencount != 0)
|
||||
return info;
|
||||
|
||||
info.truncate(++pos);
|
||||
|
||||
if (info.at(pos - 1) == ')') {
|
||||
if (info.indexOf(operator_call) == pos - (int)strlen(operator_call))
|
||||
break;
|
||||
|
||||
// this function returns a pointer to a function
|
||||
// and we matched the arguments of the return type's parameter list
|
||||
// try again
|
||||
info.remove(0, info.indexOf('('));
|
||||
info.chop(1);
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasLambda)
|
||||
info.append("::lambda");
|
||||
|
||||
// find the beginning of the function name
|
||||
int parencount = 0;
|
||||
int templatecount = 0;
|
||||
--pos;
|
||||
|
||||
// make sure special characters in operator names are kept
|
||||
if (pos > -1) {
|
||||
switch (info.at(pos)) {
|
||||
case ')':
|
||||
if (info.indexOf(operator_call) == pos - (int)strlen(operator_call) + 1)
|
||||
pos -= 2;
|
||||
break;
|
||||
case '<':
|
||||
if (info.indexOf(operator_lessThan) == pos - (int)strlen(operator_lessThan) + 1)
|
||||
--pos;
|
||||
break;
|
||||
case '>':
|
||||
if (info.indexOf(operator_greaterThan) == pos - (int)strlen(operator_greaterThan) + 1)
|
||||
--pos;
|
||||
break;
|
||||
case '=': {
|
||||
int operatorLength = (int)strlen(operator_lessThanEqual);
|
||||
if (info.indexOf(operator_lessThanEqual) == pos - operatorLength + 1)
|
||||
pos -= 2;
|
||||
else if (info.indexOf(operator_greaterThanEqual) == pos - operatorLength + 1)
|
||||
pos -= 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (pos > -1) {
|
||||
if (parencount < 0 || templatecount < 0)
|
||||
return info;
|
||||
|
||||
char c = info.at(pos);
|
||||
if (c == ')')
|
||||
++parencount;
|
||||
else if (c == '(')
|
||||
--parencount;
|
||||
else if (c == '>')
|
||||
++templatecount;
|
||||
else if (c == '<')
|
||||
--templatecount;
|
||||
else if (c == ' ' && templatecount == 0 && parencount == 0)
|
||||
break;
|
||||
|
||||
--pos;
|
||||
}
|
||||
info = info.mid(pos + 1);
|
||||
|
||||
// remove trailing '*', '&' that are part of the return argument
|
||||
while ((info.at(0) == '*')
|
||||
|| (info.at(0) == '&'))
|
||||
info = info.mid(1);
|
||||
|
||||
// we have the full function name now.
|
||||
// clean up the templates
|
||||
while ((pos = info.lastIndexOf('>')) != -1) {
|
||||
if (!info.contains('<'))
|
||||
break;
|
||||
|
||||
// find the matching close
|
||||
int end = pos;
|
||||
templatecount = 1;
|
||||
--pos;
|
||||
while (pos && templatecount) {
|
||||
register char c = info.at(pos);
|
||||
if (c == '>')
|
||||
++templatecount;
|
||||
else if (c == '<')
|
||||
--templatecount;
|
||||
--pos;
|
||||
}
|
||||
++pos;
|
||||
info.remove(pos, end - pos + 1);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
//! Returns the string to record to the logging target, formatted according to the format().
|
||||
/**
|
||||
* \sa format()
|
||||
* \sa setFormat(const QString&)
|
||||
*/
|
||||
QString AbstractStringAppender::formattedString(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file,
|
||||
int line, const char* function, const QString& category, const QString& message) const
|
||||
{
|
||||
QString f = format();
|
||||
const int size = f.size();
|
||||
|
||||
QString result;
|
||||
|
||||
int i = 0;
|
||||
while (i < f.size())
|
||||
{
|
||||
QChar c = f.at(i);
|
||||
|
||||
// We will silently ignore the broken % marker at the end of string
|
||||
if (c != QLatin1Char(formattingMarker) || (i + 2) >= size)
|
||||
{
|
||||
result.append(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
i += 2;
|
||||
QChar currentChar = f.at(i);
|
||||
QString command;
|
||||
int fieldWidth = 0;
|
||||
|
||||
if (currentChar.isLetter())
|
||||
{
|
||||
command.append(currentChar);
|
||||
int j = 1;
|
||||
while ((i + j) < size && f.at(i + j).isLetter())
|
||||
{
|
||||
command.append(f.at(i+j));
|
||||
j++;
|
||||
}
|
||||
|
||||
i+=j;
|
||||
currentChar = f.at(i);
|
||||
|
||||
// Check for the padding instruction
|
||||
if (currentChar == QLatin1Char(':'))
|
||||
{
|
||||
currentChar = f.at(++i);
|
||||
if (currentChar.isDigit() || currentChar.category() == QChar::Punctuation_Dash)
|
||||
{
|
||||
int j = 1;
|
||||
while ((i + j) < size && f.at(i + j).isDigit())
|
||||
j++;
|
||||
fieldWidth = f.mid(i, j).toInt();
|
||||
|
||||
i += j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Log record chunk to insert instead of formatting instruction
|
||||
QString chunk;
|
||||
|
||||
// Time stamp
|
||||
if (command == QLatin1String("time"))
|
||||
{
|
||||
if (f.at(i + 1) == QLatin1Char('{'))
|
||||
{
|
||||
int j = 1;
|
||||
while ((i + 2 + j) < size && f.at(i + 2 + j) != QLatin1Char('}'))
|
||||
j++;
|
||||
|
||||
if ((i + 2 + j) < size)
|
||||
{
|
||||
chunk = timeStamp.toString(f.mid(i + 2, j));
|
||||
|
||||
i += j;
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk.isNull())
|
||||
chunk = timeStamp.toString(QLatin1String("HH:mm:ss.zzz"));
|
||||
}
|
||||
|
||||
// Log level
|
||||
else if (command == QLatin1String("type"))
|
||||
chunk = Logger::levelToString(logLevel);
|
||||
|
||||
// Uppercased log level
|
||||
else if (command == QLatin1String("Type"))
|
||||
chunk = Logger::levelToString(logLevel).toUpper();
|
||||
|
||||
// One letter log level
|
||||
else if (command == QLatin1String("typeOne"))
|
||||
chunk = Logger::levelToString(logLevel).left(1).toLower();
|
||||
|
||||
// One uppercase letter log level
|
||||
else if (command == QLatin1String("TypeOne"))
|
||||
chunk = Logger::levelToString(logLevel).left(1).toUpper();
|
||||
|
||||
// Filename
|
||||
else if (command == QLatin1String("File"))
|
||||
chunk = QLatin1String(file);
|
||||
|
||||
// Filename without a path
|
||||
else if (command == QLatin1String("file"))
|
||||
chunk = QString(QLatin1String(file)).section('/', -1);
|
||||
|
||||
// Source line number
|
||||
else if (command == QLatin1String("line"))
|
||||
chunk = QString::number(line);
|
||||
|
||||
// Function name, as returned by Q_FUNC_INFO
|
||||
else if (command == QLatin1String("Function"))
|
||||
chunk = QString::fromLatin1(function);
|
||||
|
||||
// Stripped function name
|
||||
else if (command == QLatin1String("function"))
|
||||
chunk = stripFunctionName(function);
|
||||
|
||||
// Log message
|
||||
else if (command == QLatin1String("message"))
|
||||
chunk = message;
|
||||
|
||||
else if (command == QLatin1String("category"))
|
||||
chunk = category;
|
||||
|
||||
// Application pid
|
||||
else if (command == QLatin1String("pid"))
|
||||
chunk = QString::number(QCoreApplication::applicationPid());
|
||||
|
||||
// Appplication name
|
||||
else if (command == QLatin1String("appname"))
|
||||
chunk = QCoreApplication::applicationName();
|
||||
|
||||
// Thread ID (duplicates Qt5 threadid debbuging way)
|
||||
else if (command == QLatin1String("threadid"))
|
||||
chunk = QLatin1String("0x") + QString::number(qlonglong(QThread::currentThread()->currentThread()), 16);
|
||||
|
||||
// We simply replace the double formatting marker (%) with one
|
||||
else if (command == QString(formattingMarker))
|
||||
chunk = QLatin1Char(formattingMarker);
|
||||
|
||||
// Do not process any unknown commands
|
||||
else
|
||||
{
|
||||
chunk = QString(formattingMarker);
|
||||
chunk.append(command);
|
||||
}
|
||||
|
||||
result.append(QString(QLatin1String("%1")).arg(chunk, fieldWidth));
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
46
cutelogger/AbstractStringAppender.h
Normal file
46
cutelogger/AbstractStringAppender.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
#ifndef ABSTRACTSTRINGAPPENDER_H
|
||||
#define ABSTRACTSTRINGAPPENDER_H
|
||||
|
||||
// Local
|
||||
#include "CuteLogger_global.h"
|
||||
#include <AbstractAppender.h>
|
||||
|
||||
// Qt
|
||||
#include <QReadWriteLock>
|
||||
|
||||
|
||||
class CUTELOGGERSHARED_EXPORT AbstractStringAppender : public AbstractAppender
|
||||
{
|
||||
public:
|
||||
AbstractStringAppender();
|
||||
|
||||
virtual QString format() const;
|
||||
void setFormat(const QString&);
|
||||
|
||||
static QString stripFunctionName(const char*);
|
||||
|
||||
protected:
|
||||
QString formattedString(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message) const;
|
||||
|
||||
private:
|
||||
static QByteArray qCleanupFuncinfo(const char*);
|
||||
|
||||
QString m_format;
|
||||
mutable QReadWriteLock m_formatLock;
|
||||
};
|
||||
|
||||
#endif // ABSTRACTSTRINGAPPENDER_H
|
64
cutelogger/ConsoleAppender.cpp
Normal file
64
cutelogger/ConsoleAppender.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
// Local
|
||||
#include "ConsoleAppender.h"
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
|
||||
|
||||
/**
|
||||
* \class ConsoleAppender
|
||||
*
|
||||
* \brief ConsoleAppender is the simple appender that writes the log records to the std::cerr output stream.
|
||||
*
|
||||
* ConsoleAppender uses "[%{type:-7}] <%{function}> %{message}\n" as a default output format. It is similar to the
|
||||
* AbstractStringAppender but doesn't show a timestamp.
|
||||
*
|
||||
* You can modify ConsoleAppender output format without modifying your code by using \c QT_MESSAGE_PATTERN environment
|
||||
* variable. If you need your application to ignore this environment variable you can call
|
||||
* ConsoleAppender::ignoreEnvironmentPattern(true)
|
||||
*/
|
||||
|
||||
|
||||
ConsoleAppender::ConsoleAppender()
|
||||
: AbstractStringAppender(),
|
||||
m_ignoreEnvPattern(false)
|
||||
{
|
||||
setFormat("[%{type:-7}] <%{function}> %{message}\n");
|
||||
}
|
||||
|
||||
|
||||
QString ConsoleAppender::format() const
|
||||
{
|
||||
const QString envPattern = QString::fromLocal8Bit(qgetenv("QT_MESSAGE_PATTERN"));
|
||||
return (m_ignoreEnvPattern || envPattern.isEmpty()) ? AbstractStringAppender::format() : (envPattern + "\n");
|
||||
}
|
||||
|
||||
|
||||
void ConsoleAppender::ignoreEnvironmentPattern(bool ignore)
|
||||
{
|
||||
m_ignoreEnvPattern = ignore;
|
||||
}
|
||||
|
||||
|
||||
//! Writes the log record to the std::cerr stream.
|
||||
/**
|
||||
* \sa AbstractStringAppender::format()
|
||||
*/
|
||||
void ConsoleAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message)
|
||||
{
|
||||
std::cerr << qPrintable(formattedString(timeStamp, logLevel, file, line, function, category, message));
|
||||
}
|
36
cutelogger/ConsoleAppender.h
Normal file
36
cutelogger/ConsoleAppender.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
#ifndef CONSOLEAPPENDER_H
|
||||
#define CONSOLEAPPENDER_H
|
||||
|
||||
#include "CuteLogger_global.h"
|
||||
#include <AbstractStringAppender.h>
|
||||
|
||||
|
||||
class CUTELOGGERSHARED_EXPORT ConsoleAppender : public AbstractStringAppender
|
||||
{
|
||||
public:
|
||||
ConsoleAppender();
|
||||
virtual QString format() const;
|
||||
void ignoreEnvironmentPattern(bool ignore);
|
||||
|
||||
protected:
|
||||
virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message);
|
||||
|
||||
private:
|
||||
bool m_ignoreEnvPattern;
|
||||
};
|
||||
|
||||
#endif // CONSOLEAPPENDER_H
|
16
cutelogger/CuteLogger_global.h
Normal file
16
cutelogger/CuteLogger_global.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef CUTELOGGER_GLOBAL_H
|
||||
#define CUTELOGGER_GLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if defined(CUTELOGGER_LIBRARY)
|
||||
# define CUTELOGGERSHARED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
#if defined(Q_OS_WIN32)
|
||||
# define CUTELOGGERSHARED_EXPORT
|
||||
#else
|
||||
# define CUTELOGGERSHARED_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // CUTELOGGER_GLOBAL_H
|
103
cutelogger/FileAppender.cpp
Normal file
103
cutelogger/FileAppender.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
// Local
|
||||
#include "FileAppender.h"
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
|
||||
/**
|
||||
* \class FileAppender
|
||||
*
|
||||
* \brief Simple appender that writes the log records to the plain text file.
|
||||
*/
|
||||
|
||||
|
||||
//! Constructs the new file appender assigned to file with the given name.
|
||||
FileAppender::FileAppender(const QString& fileName)
|
||||
{
|
||||
setFileName(fileName);
|
||||
}
|
||||
|
||||
|
||||
FileAppender::~FileAppender()
|
||||
{
|
||||
closeFile();
|
||||
}
|
||||
|
||||
|
||||
//! Returns the name set by setFileName() or to the FileAppender constructor.
|
||||
/**
|
||||
* \sa setFileName()
|
||||
*/
|
||||
QString FileAppender::fileName() const
|
||||
{
|
||||
QMutexLocker locker(&m_logFileMutex);
|
||||
return m_logFile.fileName();
|
||||
}
|
||||
|
||||
|
||||
//! Sets the name of the file. The name can have no path, a relative path, or an absolute path.
|
||||
/**
|
||||
* \sa fileName()
|
||||
*/
|
||||
void FileAppender::setFileName(const QString& s)
|
||||
{
|
||||
QMutexLocker locker(&m_logFileMutex);
|
||||
if (m_logFile.isOpen())
|
||||
m_logFile.close();
|
||||
|
||||
m_logFile.setFileName(s);
|
||||
}
|
||||
|
||||
|
||||
bool FileAppender::openFile()
|
||||
{
|
||||
bool isOpen = m_logFile.isOpen();
|
||||
if (!isOpen)
|
||||
{
|
||||
isOpen = m_logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
|
||||
if (isOpen)
|
||||
m_logStream.setDevice(&m_logFile);
|
||||
else
|
||||
std::cerr << "<FileAppender::append> Cannot open the log file " << qPrintable(m_logFile.fileName()) << std::endl;
|
||||
}
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
|
||||
//! Write the log record to the file.
|
||||
/**
|
||||
* \sa fileName()
|
||||
* \sa AbstractStringAppender::format()
|
||||
*/
|
||||
void FileAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message)
|
||||
{
|
||||
QMutexLocker locker(&m_logFileMutex);
|
||||
|
||||
if (openFile())
|
||||
{
|
||||
m_logStream << formattedString(timeStamp, logLevel, file, line, function, category, message);
|
||||
m_logStream.flush();
|
||||
m_logFile.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileAppender::closeFile()
|
||||
{
|
||||
QMutexLocker locker(&m_logFileMutex);
|
||||
m_logFile.close();
|
||||
}
|
47
cutelogger/FileAppender.h
Normal file
47
cutelogger/FileAppender.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2010 Boris Moiseev (cyberbobs at gmail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
#ifndef FILEAPPENDER_H
|
||||
#define FILEAPPENDER_H
|
||||
|
||||
// Logger
|
||||
#include "CuteLogger_global.h"
|
||||
#include <AbstractStringAppender.h>
|
||||
|
||||
// Qt
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
|
||||
class CUTELOGGERSHARED_EXPORT FileAppender : public AbstractStringAppender
|
||||
{
|
||||
public:
|
||||
FileAppender(const QString& fileName = QString());
|
||||
~FileAppender();
|
||||
|
||||
QString fileName() const;
|
||||
void setFileName(const QString&);
|
||||
|
||||
protected:
|
||||
virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message);
|
||||
bool openFile();
|
||||
void closeFile();
|
||||
|
||||
private:
|
||||
QFile m_logFile;
|
||||
QTextStream m_logStream;
|
||||
mutable QMutex m_logFileMutex;
|
||||
};
|
||||
|
||||
#endif // FILEAPPENDER_H
|
1104
cutelogger/Logger.cpp
Normal file
1104
cutelogger/Logger.cpp
Normal file
File diff suppressed because it is too large
Load Diff
206
cutelogger/Logger.h
Normal file
206
cutelogger/Logger.h
Normal file
@ -0,0 +1,206 @@
|
||||
/*
|
||||
Copyright (c) 2012 Boris Moiseev (cyberbobs at gmail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
// Qt
|
||||
#include <QString>
|
||||
#include <QDebug>
|
||||
#include <QDateTime>
|
||||
|
||||
// Local
|
||||
#include "CuteLogger_global.h"
|
||||
class AbstractAppender;
|
||||
|
||||
|
||||
class Logger;
|
||||
CUTELOGGERSHARED_EXPORT Logger* loggerInstance();
|
||||
#define logger loggerInstance()
|
||||
|
||||
|
||||
#define LOG_TRACE CuteMessageLogger(loggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO).write
|
||||
#define LOG_DEBUG CuteMessageLogger(loggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO).write
|
||||
#define LOG_INFO CuteMessageLogger(loggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO).write
|
||||
#define LOG_WARNING CuteMessageLogger(loggerInstance(), Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO).write
|
||||
#define LOG_ERROR CuteMessageLogger(loggerInstance(), Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO).write
|
||||
#define LOG_FATAL CuteMessageLogger(loggerInstance(), Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO).write
|
||||
|
||||
#define LOG_CTRACE(category) CuteMessageLogger(loggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
|
||||
#define LOG_CDEBUG(category) CuteMessageLogger(loggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
|
||||
#define LOG_CINFO(category) CuteMessageLogger(loggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
|
||||
#define LOG_CWARNING(category) CuteMessageLogger(loggerInstance(), Logger::Warning, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
|
||||
#define LOG_CERROR(category) CuteMessageLogger(loggerInstance(), Logger::Error, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
|
||||
#define LOG_CFATAL(category) CuteMessageLogger(loggerInstance(), Logger::Fatal, __FILE__, __LINE__, Q_FUNC_INFO, category).write()
|
||||
|
||||
#define LOG_TRACE_TIME LoggerTimingHelper loggerTimingHelper(loggerInstance(), Logger::Trace, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
|
||||
#define LOG_DEBUG_TIME LoggerTimingHelper loggerTimingHelper(loggerInstance(), Logger::Debug, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
|
||||
#define LOG_INFO_TIME LoggerTimingHelper loggerTimingHelper(loggerInstance(), Logger::Info, __FILE__, __LINE__, Q_FUNC_INFO); loggerTimingHelper.start
|
||||
|
||||
#define LOG_ASSERT(cond) ((!(cond)) ? loggerInstance()->writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, #cond) : qt_noop())
|
||||
#define LOG_ASSERT_X(cond, msg) ((!(cond)) ? loggerInstance()->writeAssert(__FILE__, __LINE__, Q_FUNC_INFO, msg) : qt_noop())
|
||||
|
||||
#define LOG_CATEGORY(category) \
|
||||
private:\
|
||||
Logger* loggerInstance()\
|
||||
{\
|
||||
static Logger customLoggerInstance(category);\
|
||||
return &customLoggerInstance;\
|
||||
}\
|
||||
|
||||
#define LOG_GLOBAL_CATEGORY(category) \
|
||||
private:\
|
||||
Logger* loggerInstance()\
|
||||
{\
|
||||
static Logger customLoggerInstance(category);\
|
||||
customLoggerInstance.logToGlobalInstance(category, true);\
|
||||
return &customLoggerInstance;\
|
||||
}\
|
||||
|
||||
|
||||
class LoggerPrivate;
|
||||
class CUTELOGGERSHARED_EXPORT Logger
|
||||
{
|
||||
Q_DISABLE_COPY(Logger)
|
||||
|
||||
public:
|
||||
Logger();
|
||||
Logger(const QString& defaultCategory);
|
||||
~Logger();
|
||||
|
||||
//! Describes the possible severity levels of the log records
|
||||
enum LogLevel
|
||||
{
|
||||
Trace, //!< Trace level. Can be used for mostly unneeded records used for internal code tracing.
|
||||
Debug, //!< Debug level. Useful for non-necessary records used for the debugging of the software.
|
||||
Info, //!< Info level. Can be used for informational records, which may be interesting for not only developers.
|
||||
Warning, //!< Warning. May be used to log some non-fatal warnings detected by your application.
|
||||
Error, //!< Error. May be used for a big problems making your application work wrong but not crashing.
|
||||
Fatal //!< Fatal. Used for unrecoverable errors, crashes the application right after the log record is written.
|
||||
};
|
||||
|
||||
static QString levelToString(LogLevel logLevel);
|
||||
static LogLevel levelFromString(const QString& s);
|
||||
|
||||
static Logger* globalInstance();
|
||||
|
||||
void registerAppender(AbstractAppender* appender);
|
||||
void registerCategoryAppender(const QString& category, AbstractAppender* appender);
|
||||
|
||||
void logToGlobalInstance(const QString& category, bool logToGlobal = false);
|
||||
|
||||
void setDefaultCategory(const QString& category);
|
||||
QString defaultCategory() const;
|
||||
|
||||
void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category,
|
||||
const QString& message);
|
||||
void write(LogLevel logLevel, const char* file, int line, const char* function, const char* category, const QString& message);
|
||||
QDebug write(LogLevel logLevel, const char* file, int line, const char* function, const char* category);
|
||||
|
||||
void writeAssert(const char* file, int line, const char* function, const char* condition);
|
||||
|
||||
private:
|
||||
void write(const QDateTime& timeStamp, LogLevel logLevel, const char* file, int line, const char* function, const char* category,
|
||||
const QString& message, bool fromLocalInstance);
|
||||
Q_DECLARE_PRIVATE(Logger)
|
||||
LoggerPrivate* d_ptr;
|
||||
};
|
||||
|
||||
|
||||
class CUTELOGGERSHARED_EXPORT CuteMessageLogger
|
||||
{
|
||||
Q_DISABLE_COPY(CuteMessageLogger)
|
||||
|
||||
public:
|
||||
Q_DECL_CONSTEXPR CuteMessageLogger(Logger* l, Logger::LogLevel level, const char* file, int line, const char* function)
|
||||
: m_l(l),
|
||||
m_level(level),
|
||||
m_file(file),
|
||||
m_line(line),
|
||||
m_function(function),
|
||||
m_category(0)
|
||||
{}
|
||||
|
||||
Q_DECL_CONSTEXPR CuteMessageLogger(Logger* l, Logger::LogLevel level, const char* file, int line, const char* function, const char* category)
|
||||
: m_l(l),
|
||||
m_level(level),
|
||||
m_file(file),
|
||||
m_line(line),
|
||||
m_function(function),
|
||||
m_category(category)
|
||||
{}
|
||||
|
||||
void write(const char* msg, ...) const
|
||||
#if defined(Q_CC_GNU) && !defined(__INSURE__)
|
||||
# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
|
||||
__attribute__ ((format (gnu_printf, 2, 3)))
|
||||
# else
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
# endif
|
||||
#endif
|
||||
;
|
||||
|
||||
void write(const QString& msg) const;
|
||||
|
||||
QDebug write() const;
|
||||
|
||||
private:
|
||||
Logger* m_l;
|
||||
Logger::LogLevel m_level;
|
||||
const char* m_file;
|
||||
int m_line;
|
||||
const char* m_function;
|
||||
const char* m_category;
|
||||
};
|
||||
|
||||
|
||||
class CUTELOGGERSHARED_EXPORT LoggerTimingHelper
|
||||
{
|
||||
Q_DISABLE_COPY(LoggerTimingHelper)
|
||||
|
||||
public:
|
||||
inline explicit LoggerTimingHelper(Logger* l, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function)
|
||||
: m_logger(l),
|
||||
m_logLevel(logLevel),
|
||||
m_file(file),
|
||||
m_line(line),
|
||||
m_function(function)
|
||||
{}
|
||||
|
||||
void start(const char* msg, ...)
|
||||
#if defined(Q_CC_GNU) && !defined(__INSURE__)
|
||||
# if defined(Q_CC_MINGW) && !defined(Q_CC_CLANG)
|
||||
__attribute__ ((format (gnu_printf, 2, 3)))
|
||||
# else
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
# endif
|
||||
#endif
|
||||
;
|
||||
|
||||
void start(const QString& msg = QString());
|
||||
|
||||
~LoggerTimingHelper();
|
||||
|
||||
private:
|
||||
Logger* m_logger;
|
||||
QTime m_time;
|
||||
Logger::LogLevel m_logLevel;
|
||||
const char* m_file;
|
||||
int m_line;
|
||||
const char* m_function;
|
||||
QString m_block;
|
||||
};
|
||||
|
||||
|
||||
#endif // LOGGER_H
|
43
cutelogger/OutputDebugAppender.cpp
Normal file
43
cutelogger/OutputDebugAppender.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright (c) 2010 Karl-Heinz Reichel (khreichel at googlemail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
// Local
|
||||
#include "OutputDebugAppender.h"
|
||||
|
||||
// STL
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
/**
|
||||
* \class OutputDebugAppender
|
||||
*
|
||||
* \brief Appender that writes the log records to the Microsoft Debug Log
|
||||
*/
|
||||
|
||||
|
||||
//! Writes the log record to the windows debug log.
|
||||
/**
|
||||
* \sa AbstractStringAppender::format()
|
||||
*/
|
||||
void OutputDebugAppender::append(const QDateTime& timeStamp,
|
||||
Logger::LogLevel logLevel,
|
||||
const char* file,
|
||||
int line,
|
||||
const char* function,
|
||||
const QString& category,
|
||||
const QString& message)
|
||||
{
|
||||
QString s = formattedString(timeStamp, logLevel, file, line, function, category, message);
|
||||
OutputDebugStringW((LPCWSTR) s.utf16());
|
||||
}
|
||||
|
29
cutelogger/OutputDebugAppender.h
Normal file
29
cutelogger/OutputDebugAppender.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright (c) 2010 Karl-Heinz Reichel (khreichel at googlemail dot com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License version 2.1
|
||||
as published by the Free Software Foundation and appearing in the file
|
||||
LICENSE.LGPL included in the packaging of this file.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef OUTPUTDEBUGAPPENDER_H
|
||||
#define OUTPUTDEBUGAPPENDER_H
|
||||
|
||||
#include "CuteLogger_global.h"
|
||||
#include <AbstractStringAppender.h>
|
||||
|
||||
|
||||
class CUTELOGGERSHARED_EXPORT OutputDebugAppender : public AbstractStringAppender
|
||||
{
|
||||
protected:
|
||||
virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message);
|
||||
};
|
||||
|
||||
#endif // OUTPUTDEBUGAPPENDER_H
|
248
cutelogger/RollingFileAppender.cpp
Normal file
248
cutelogger/RollingFileAppender.cpp
Normal file
@ -0,0 +1,248 @@
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "RollingFileAppender.h"
|
||||
|
||||
|
||||
RollingFileAppender::RollingFileAppender(const QString& fileName)
|
||||
: FileAppender(fileName),
|
||||
m_logFilesLimit(0)
|
||||
{}
|
||||
|
||||
|
||||
void RollingFileAppender::append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message)
|
||||
{
|
||||
if (!m_rollOverTime.isNull() && QDateTime::currentDateTime() > m_rollOverTime)
|
||||
rollOver();
|
||||
|
||||
FileAppender::append(timeStamp, logLevel, file, line, function, category, message);
|
||||
}
|
||||
|
||||
|
||||
RollingFileAppender::DatePattern RollingFileAppender::datePattern() const
|
||||
{
|
||||
QMutexLocker locker(&m_rollingMutex);
|
||||
return m_frequency;
|
||||
}
|
||||
|
||||
|
||||
QString RollingFileAppender::datePatternString() const
|
||||
{
|
||||
QMutexLocker locker(&m_rollingMutex);
|
||||
return m_datePatternString;
|
||||
}
|
||||
|
||||
|
||||
void RollingFileAppender::setDatePattern(DatePattern datePattern)
|
||||
{
|
||||
switch (datePattern)
|
||||
{
|
||||
case MinutelyRollover:
|
||||
setDatePatternString(QLatin1String("'.'yyyy-MM-dd-hh-mm"));
|
||||
break;
|
||||
case HourlyRollover:
|
||||
setDatePatternString(QLatin1String("'.'yyyy-MM-dd-hh"));
|
||||
break;
|
||||
case HalfDailyRollover:
|
||||
setDatePatternString(QLatin1String("'.'yyyy-MM-dd-a"));
|
||||
break;
|
||||
case DailyRollover:
|
||||
setDatePatternString(QLatin1String("'.'yyyy-MM-dd"));
|
||||
break;
|
||||
case WeeklyRollover:
|
||||
setDatePatternString(QLatin1String("'.'yyyy-ww"));
|
||||
break;
|
||||
case MonthlyRollover:
|
||||
setDatePatternString(QLatin1String("'.'yyyy-MM"));
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT_X(false, "DailyRollingFileAppender::setDatePattern()", "Invalid datePattern constant");
|
||||
setDatePattern(DailyRollover);
|
||||
};
|
||||
|
||||
QMutexLocker locker(&m_rollingMutex);
|
||||
m_frequency = datePattern;
|
||||
|
||||
computeRollOverTime();
|
||||
}
|
||||
|
||||
|
||||
void RollingFileAppender::setDatePattern(const QString& datePattern)
|
||||
{
|
||||
setDatePatternString(datePattern);
|
||||
computeFrequency();
|
||||
|
||||
computeRollOverTime();
|
||||
}
|
||||
|
||||
|
||||
void RollingFileAppender::setDatePatternString(const QString& datePatternString)
|
||||
{
|
||||
QMutexLocker locker(&m_rollingMutex);
|
||||
m_datePatternString = datePatternString;
|
||||
}
|
||||
|
||||
|
||||
void RollingFileAppender::computeFrequency()
|
||||
{
|
||||
QMutexLocker locker(&m_rollingMutex);
|
||||
|
||||
const QDateTime startTime(QDate(1999, 1, 1), QTime(0, 0));
|
||||
const QString startString = startTime.toString(m_datePatternString);
|
||||
|
||||
if (startString != startTime.addSecs(60).toString(m_datePatternString))
|
||||
m_frequency = MinutelyRollover;
|
||||
else if (startString != startTime.addSecs(60 * 60).toString(m_datePatternString))
|
||||
m_frequency = HourlyRollover;
|
||||
else if (startString != startTime.addSecs(60 * 60 * 12).toString(m_datePatternString))
|
||||
m_frequency = HalfDailyRollover;
|
||||
else if (startString != startTime.addDays(1).toString(m_datePatternString))
|
||||
m_frequency = DailyRollover;
|
||||
else if (startString != startTime.addDays(7).toString(m_datePatternString))
|
||||
m_frequency = WeeklyRollover;
|
||||
else if (startString != startTime.addMonths(1).toString(m_datePatternString))
|
||||
m_frequency = MonthlyRollover;
|
||||
else
|
||||
{
|
||||
Q_ASSERT_X(false, "DailyRollingFileAppender::computeFrequency", "The pattern '%1' does not specify a frequency");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RollingFileAppender::removeOldFiles()
|
||||
{
|
||||
if (m_logFilesLimit <= 1)
|
||||
return;
|
||||
|
||||
QFileInfo fileInfo(fileName());
|
||||
QDir logDirectory(fileInfo.absoluteDir());
|
||||
logDirectory.setFilter(QDir::Files);
|
||||
logDirectory.setNameFilters(QStringList() << fileInfo.fileName() + "*");
|
||||
QFileInfoList logFiles = logDirectory.entryInfoList();
|
||||
|
||||
QMap<QDateTime, QString> fileDates;
|
||||
for (int i = 0; i < logFiles.length(); ++i)
|
||||
{
|
||||
QString name = logFiles[i].fileName();
|
||||
QString suffix = name.mid(name.indexOf(fileInfo.fileName()) + fileInfo.fileName().length());
|
||||
QDateTime fileDateTime = QDateTime::fromString(suffix, datePatternString());
|
||||
|
||||
if (fileDateTime.isValid())
|
||||
fileDates.insert(fileDateTime, logFiles[i].absoluteFilePath());
|
||||
}
|
||||
|
||||
QList<QString> fileDateNames = fileDates.values();
|
||||
for (int i = 0; i < fileDateNames.length() - m_logFilesLimit + 1; ++i)
|
||||
QFile::remove(fileDateNames[i]);
|
||||
}
|
||||
|
||||
|
||||
void RollingFileAppender::computeRollOverTime()
|
||||
{
|
||||
Q_ASSERT_X(!m_datePatternString.isEmpty(), "DailyRollingFileAppender::computeRollOverTime()", "No active date pattern");
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QDate nowDate = now.date();
|
||||
QTime nowTime = now.time();
|
||||
QDateTime start;
|
||||
|
||||
switch (m_frequency)
|
||||
{
|
||||
case MinutelyRollover:
|
||||
{
|
||||
start = QDateTime(nowDate, QTime(nowTime.hour(), nowTime.minute(), 0, 0));
|
||||
m_rollOverTime = start.addSecs(60);
|
||||
}
|
||||
break;
|
||||
case HourlyRollover:
|
||||
{
|
||||
start = QDateTime(nowDate, QTime(nowTime.hour(), 0, 0, 0));
|
||||
m_rollOverTime = start.addSecs(60*60);
|
||||
}
|
||||
break;
|
||||
case HalfDailyRollover:
|
||||
{
|
||||
int hour = nowTime.hour();
|
||||
if (hour >= 12)
|
||||
hour = 12;
|
||||
else
|
||||
hour = 0;
|
||||
start = QDateTime(nowDate, QTime(hour, 0, 0, 0));
|
||||
m_rollOverTime = start.addSecs(60*60*12);
|
||||
}
|
||||
break;
|
||||
case DailyRollover:
|
||||
{
|
||||
start = QDateTime(nowDate, QTime(0, 0, 0, 0));
|
||||
m_rollOverTime = start.addDays(1);
|
||||
}
|
||||
break;
|
||||
case WeeklyRollover:
|
||||
{
|
||||
// Qt numbers the week days 1..7. The week starts on Monday.
|
||||
// Change it to being numbered 0..6, starting with Sunday.
|
||||
int day = nowDate.dayOfWeek();
|
||||
if (day == Qt::Sunday)
|
||||
day = 0;
|
||||
start = QDateTime(nowDate, QTime(0, 0, 0, 0)).addDays(-1 * day);
|
||||
m_rollOverTime = start.addDays(7);
|
||||
}
|
||||
break;
|
||||
case MonthlyRollover:
|
||||
{
|
||||
start = QDateTime(QDate(nowDate.year(), nowDate.month(), 1), QTime(0, 0, 0, 0));
|
||||
m_rollOverTime = start.addMonths(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT_X(false, "DailyRollingFileAppender::computeInterval()", "Invalid datePattern constant");
|
||||
m_rollOverTime = QDateTime::fromTime_t(0);
|
||||
}
|
||||
|
||||
m_rollOverSuffix = start.toString(m_datePatternString);
|
||||
Q_ASSERT_X(now.toString(m_datePatternString) == m_rollOverSuffix,
|
||||
"DailyRollingFileAppender::computeRollOverTime()", "File name changes within interval");
|
||||
Q_ASSERT_X(m_rollOverSuffix != m_rollOverTime.toString(m_datePatternString),
|
||||
"DailyRollingFileAppender::computeRollOverTime()", "File name does not change with rollover");
|
||||
}
|
||||
|
||||
|
||||
void RollingFileAppender::rollOver()
|
||||
{
|
||||
Q_ASSERT_X(!m_datePatternString.isEmpty(), "DailyRollingFileAppender::rollOver()", "No active date pattern");
|
||||
|
||||
QString rollOverSuffix = m_rollOverSuffix;
|
||||
computeRollOverTime();
|
||||
if (rollOverSuffix == m_rollOverSuffix)
|
||||
return;
|
||||
|
||||
closeFile();
|
||||
|
||||
QString targetFileName = fileName() + rollOverSuffix;
|
||||
QFile f(targetFileName);
|
||||
if (f.exists() && !f.remove())
|
||||
return;
|
||||
f.setFileName(fileName());
|
||||
if (!f.rename(targetFileName))
|
||||
return;
|
||||
|
||||
openFile();
|
||||
removeOldFiles();
|
||||
}
|
||||
|
||||
|
||||
void RollingFileAppender::setLogFilesLimit(int limit)
|
||||
{
|
||||
QMutexLocker locker(&m_rollingMutex);
|
||||
m_logFilesLimit = limit;
|
||||
}
|
||||
|
||||
|
||||
int RollingFileAppender::logFilesLimit() const
|
||||
{
|
||||
QMutexLocker locker(&m_rollingMutex);
|
||||
return m_logFilesLimit;
|
||||
}
|
77
cutelogger/RollingFileAppender.h
Normal file
77
cutelogger/RollingFileAppender.h
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef ROLLINGFILEAPPENDER_H
|
||||
#define ROLLINGFILEAPPENDER_H
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
#include <FileAppender.h>
|
||||
|
||||
/*!
|
||||
* \brief The RollingFileAppender class extends FileAppender so that the underlying file is rolled over at a user chosen frequency.
|
||||
*
|
||||
* The class is based on Log4Qt.DailyRollingFileAppender class (http://log4qt.sourceforge.net/)
|
||||
* and has the same date pattern format.
|
||||
*
|
||||
* For example, if the fileName is set to /foo/bar and the DatePattern set to the daily rollover ('.'yyyy-MM-dd'.log'), on 2014-02-16 at midnight,
|
||||
* the logging file /foo/bar.log will be copied to /foo/bar.2014-02-16.log and logging for 2014-02-17 will continue in /foo/bar
|
||||
* until it rolls over the next day.
|
||||
*
|
||||
* The logFilesLimit parameter is used to automatically delete the oldest log files in the directory during rollover
|
||||
* (so no more than logFilesLimit recent log files exist in the directory at any moment).
|
||||
* \sa setDatePattern(DatePattern), setLogFilesLimit(int)
|
||||
*/
|
||||
class CUTELOGGERSHARED_EXPORT RollingFileAppender : public FileAppender
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* The enum DatePattern defines constants for date patterns.
|
||||
* \sa setDatePattern(DatePattern)
|
||||
*/
|
||||
enum DatePattern
|
||||
{
|
||||
/*! The minutely date pattern string is "'.'yyyy-MM-dd-hh-mm". */
|
||||
MinutelyRollover = 0,
|
||||
/*! The hourly date pattern string is "'.'yyyy-MM-dd-hh". */
|
||||
HourlyRollover,
|
||||
/*! The half-daily date pattern string is "'.'yyyy-MM-dd-a". */
|
||||
HalfDailyRollover,
|
||||
/*! The daily date pattern string is "'.'yyyy-MM-dd". */
|
||||
DailyRollover,
|
||||
/*! The weekly date pattern string is "'.'yyyy-ww". */
|
||||
WeeklyRollover,
|
||||
/*! The monthly date pattern string is "'.'yyyy-MM". */
|
||||
MonthlyRollover
|
||||
};
|
||||
Q_ENUMS(DatePattern)
|
||||
|
||||
RollingFileAppender(const QString& fileName = QString());
|
||||
|
||||
DatePattern datePattern() const;
|
||||
void setDatePattern(DatePattern datePattern);
|
||||
void setDatePattern(const QString& datePattern);
|
||||
|
||||
QString datePatternString() const;
|
||||
|
||||
void setLogFilesLimit(int limit);
|
||||
int logFilesLimit() const;
|
||||
|
||||
protected:
|
||||
virtual void append(const QDateTime& timeStamp, Logger::LogLevel logLevel, const char* file, int line,
|
||||
const char* function, const QString& category, const QString& message);
|
||||
|
||||
private:
|
||||
void rollOver();
|
||||
void computeRollOverTime();
|
||||
void computeFrequency();
|
||||
void removeOldFiles();
|
||||
void setDatePatternString(const QString& datePatternString);
|
||||
|
||||
QString m_datePatternString;
|
||||
DatePattern m_frequency;
|
||||
|
||||
QDateTime m_rollOverTime;
|
||||
QString m_rollOverSuffix;
|
||||
int m_logFilesLimit;
|
||||
mutable QMutex m_rollingMutex;
|
||||
};
|
||||
|
||||
#endif // ROLLINGFILEAPPENDER_H
|
25
cutelogger/cutelogger.pri
Normal file
25
cutelogger/cutelogger.pri
Normal file
@ -0,0 +1,25 @@
|
||||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/RollingFileAppender.h \
|
||||
$$PWD/Logger.h \
|
||||
$$PWD/FileAppender.h \
|
||||
$$PWD/CuteLogger_global.h \
|
||||
$$PWD/ConsoleAppender.h \
|
||||
$$PWD/AbstractStringAppender.h \
|
||||
$$PWD/AbstractAppender.h \
|
||||
$$PWD/logmanager.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/RollingFileAppender.cpp \
|
||||
$$PWD/Logger.cpp \
|
||||
$$PWD/FileAppender.cpp \
|
||||
$$PWD/ConsoleAppender.cpp \
|
||||
$$PWD/AbstractStringAppender.cpp \
|
||||
$$PWD/AbstractAppender.cpp \
|
||||
$$PWD/logmanager.cpp
|
||||
|
||||
win32 {
|
||||
SOURCES += $$PWD/OutputDebugAppender.cpp
|
||||
HEADERS += $$PWD/OutputDebugAppender.h
|
||||
}
|
51
cutelogger/logmanager.cpp
Normal file
51
cutelogger/logmanager.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include "logmanager.h"
|
||||
#include <Logger.h>
|
||||
#include <ConsoleAppender.h>
|
||||
#include <RollingFileAppender.h>
|
||||
|
||||
LogManager::LogManager()
|
||||
{
|
||||
m_format = "%{time}{dd-MM-yyyy, HH:mm:ss.zzz} [%{type:-7}] [%{file:-25} %{line}] %{message}\n";
|
||||
}
|
||||
|
||||
void LogManager::initConsoleAppender(){
|
||||
m_consoleAppender = new ConsoleAppender;
|
||||
m_consoleAppender->setFormat(m_format);
|
||||
logger->registerAppender(m_consoleAppender);
|
||||
}
|
||||
|
||||
void LogManager::initRollingFileAppender(){
|
||||
QString cachePath = QStandardPaths::standardLocations(QStandardPaths::CacheLocation).at(0);
|
||||
if (!QDir(cachePath).exists()){
|
||||
QDir(cachePath).mkpath(cachePath);
|
||||
}
|
||||
m_logPath = joinPath(cachePath, QString("%1.log").arg(qApp->applicationName()));
|
||||
m_rollingFileAppender = new RollingFileAppender(m_logPath);
|
||||
m_rollingFileAppender->setFormat(m_format);
|
||||
m_rollingFileAppender->setLogFilesLimit(5);
|
||||
m_rollingFileAppender->setDatePattern(RollingFileAppender::DailyRollover);
|
||||
logger->registerAppender(m_rollingFileAppender);
|
||||
}
|
||||
|
||||
void LogManager::debug_log_console_on(){
|
||||
#if !defined(QT_NO_DEBUG)
|
||||
LogManager::instance()->initConsoleAppender();
|
||||
#endif
|
||||
LogManager::instance()->initRollingFileAppender();
|
||||
}
|
||||
|
||||
|
||||
QString LogManager::joinPath(const QString &path, const QString &fileName){
|
||||
QString separator(QDir::separator());
|
||||
return QString("%1%2%3").arg(path, separator, fileName);
|
||||
}
|
||||
|
||||
|
||||
QString LogManager::getlogFilePath(){
|
||||
return m_logPath;
|
||||
}
|
||||
|
||||
LogManager::~LogManager()
|
||||
{
|
||||
|
||||
}
|
41
cutelogger/logmanager.h
Normal file
41
cutelogger/logmanager.h
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef LOGMANAGER_H
|
||||
#define LOGMANAGER_H
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class ConsoleAppender;
|
||||
class RollingFileAppender;
|
||||
|
||||
class LogManager
|
||||
{
|
||||
public:
|
||||
void initConsoleAppender();
|
||||
void initRollingFileAppender();
|
||||
|
||||
inline static LogManager* instance(){
|
||||
static LogManager instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void debug_log_console_on();
|
||||
QString joinPath(const QString& path, const QString& fileName);
|
||||
QString getlogFilePath();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private:
|
||||
QString m_format;
|
||||
QString m_logPath;
|
||||
ConsoleAppender* m_consoleAppender;
|
||||
RollingFileAppender* m_rollingFileAppender;
|
||||
|
||||
|
||||
explicit LogManager();
|
||||
~LogManager();
|
||||
LogManager(const LogManager &);
|
||||
LogManager & operator = (const LogManager &);
|
||||
};
|
||||
|
||||
#endif // LOGMANAGER_H
|
@ -28,7 +28,7 @@ headers.files += src/interfaces/dockconstants.h \
|
||||
src/interfaces/dockplugininterface.h \
|
||||
src/interfaces/dockpluginproxyinterface.h
|
||||
headers.path = /usr/include/dde-dock
|
||||
|
||||
include (../cutelogger/cutelogger.pri)
|
||||
INSTALLS += headers target
|
||||
|
||||
HEADERS += \
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include <QDBusConnection>
|
||||
|
||||
#include "mainwidget.h"
|
||||
#include "logmanager.h"
|
||||
#include "Logger.h"
|
||||
|
||||
// let startdde know that we've already started.
|
||||
void RegisterDdeSession()
|
||||
@ -29,6 +31,9 @@ int main(int argc, char *argv[])
|
||||
a.setApplicationName("dde-dock");
|
||||
a.setApplicationDisplayName("Dock");
|
||||
|
||||
LogManager::instance()->debug_log_console_on();
|
||||
LOG_INFO() << LogManager::instance()->getlogFilePath();
|
||||
|
||||
if (QDBusConnection::sessionBus().registerService(DBUS_NAME)) {
|
||||
QFile file("://qss/resources/dark/qss/dde-dock.qss");
|
||||
if (file.open(QFile::ReadOnly)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user