如何编写自己的日志类



伙计们,我想按类型划分,例如WARNING和INFO日志应该保存在其他文件中。。。下面是QXmpp库的类QXmppLogger,它将所有日志记录类型保存到一个文件中,但我必须按照前面提到的方式进行。有人能指引我通过吗

PS我不能更改QXmppLogger类!

QXmppLogger.h

#ifndef QXMPPLOGGER_H
#define QXMPPLOGGER_H
#include <QObject>
#include "QXmppGlobal.h"
#ifdef QXMPP_LOGGABLE_TRACE
#define qxmpp_loggable_trace(x) QString("%1(0x%2) %3").arg(metaObject()->className(), QString::number(reinterpret_cast<qint64>(this), 16), x)
#else
#define qxmpp_loggable_trace(x) (x)
#endif
class QXmppLoggerPrivate;
/// brief The QXmppLogger class represents a sink for logging messages.
///
/// ingroup Core
class QXMPP_EXPORT QXmppLogger : public QObject
{
    Q_OBJECT
    Q_ENUMS(LoggingType)
    Q_FLAGS(MessageType MessageTypes)
    Q_PROPERTY(QString logFilePath READ logFilePath WRITE setLogFilePath)
    Q_PROPERTY(LoggingType loggingType READ loggingType WRITE setLoggingType)
    Q_PROPERTY(MessageTypes messageTypes READ messageTypes WRITE setMessageTypes)
public:
    /// This enum describes how log message are handled.
    enum LoggingType
    {
        NoLogging = 0,      ///< Log messages are discarded
        FileLogging = 1,    ///< Log messages are written to a file
        StdoutLogging = 2,  ///< Log messages are written to the standard output
        SignalLogging = 4,  ///< Log messages are emitted as a signal
    };
    /// This enum describes a type of log message.
    enum MessageType
    {
        NoMessage = 0,          ///< No message type
        DebugMessage = 1,       ///< Debugging message
        InformationMessage = 2, ///< Informational message
        WarningMessage = 4,     ///< Warning message
        ReceivedMessage = 8,    ///< Message received from server
        SentMessage = 16,       ///< Message sent to server
        AnyMessage = 31,        ///< Any message type
    };
    Q_DECLARE_FLAGS(MessageTypes, MessageType)
    QXmppLogger(QObject *parent = 0);
    ~QXmppLogger();
    static QXmppLogger* getLogger();
    QXmppLogger::LoggingType loggingType();
    void setLoggingType(QXmppLogger::LoggingType type);
    QString logFilePath();
    void setLogFilePath(const QString &path);
    QXmppLogger::MessageTypes messageTypes();
    void setMessageTypes(QXmppLogger::MessageTypes types);
public slots:
    virtual void setGauge(const QString &gauge, double value);
    virtual void updateCounter(const QString &counter, qint64 amount);
    void log(QXmppLogger::MessageType type, const QString& text);
    void reopen();
signals:
    /// This signal is emitted whenever a log message is received.
    void message(QXmppLogger::MessageType type, const QString &text);
private:
    static QXmppLogger* m_logger;
    QXmppLoggerPrivate *d;
};
/// brief The QXmppLoggable class represents a source of logging messages.
///
/// ingroup Core
class QXMPP_EXPORT QXmppLoggable : public QObject
{
    Q_OBJECT
public:
    QXmppLoggable(QObject *parent = 0);
protected:
    /// cond
    virtual void childEvent(QChildEvent *event);
    /// endcond
    /// Logs a debugging message.
    ///
    /// param message
    void debug(const QString &message)
    {
        emit logMessage(QXmppLogger::DebugMessage, qxmpp_loggable_trace(message));
    }
    /// Logs an informational message.
    ///
    /// param message
    void info(const QString &message)
    {
        emit logMessage(QXmppLogger::InformationMessage, qxmpp_loggable_trace(message));
    }
    /// Logs a warning message.
    ///
    /// param message
    void warning(const QString &message)
    {
        emit logMessage(QXmppLogger::WarningMessage, qxmpp_loggable_trace(message));
    }
    /// Logs a received packet.
    ///
    /// param message
    void logReceived(const QString &message)
    {
        emit logMessage(QXmppLogger::ReceivedMessage, qxmpp_loggable_trace(message));
    }
    /// Logs a sent packet.
    ///
    /// param message
    void logSent(const QString &message)
    {
        emit logMessage(QXmppLogger::SentMessage, qxmpp_loggable_trace(message));
    }
signals:
    /// Sets the given a gauge to a value.
    void setGauge(const QString &gauge, double value);
    /// This signal is emitted to send logging messages.
    void logMessage(QXmppLogger::MessageType type, const QString &msg);
    /// Updates the given a counter by a amount.
    void updateCounter(const QString &counter, qint64 amount = 1);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QXmppLogger::MessageTypes)
   #endif // QXMPPLOGGER_H

这是QXmppLogger.cpp

#include <iostream>
#include <QChildEvent>
#include <QDateTime>
#include <QFile>
#include <QMetaType>
#include <QTextStream>
#include "QXmppLogger.h"
QXmppLogger* QXmppLogger::m_logger = 0;
static const char *typeName(QXmppLogger::MessageType type)
{
    switch (type)
    {
    case QXmppLogger::DebugMessage:
        return "DEBUG";
    case QXmppLogger::InformationMessage:
        return "INFO";
    case QXmppLogger::WarningMessage:
        return "WARNING";
    case QXmppLogger::ReceivedMessage:
        return "RECEIVED";
    case QXmppLogger::SentMessage:
        return "SENT";
    default:
        return "";
    }
}
static QString formatted(QXmppLogger::MessageType type, const QString& text)
{
    return QDateTime::currentDateTime().toString() + " " +
        QString::fromLatin1(typeName(type)) + " " +
        text;
}
static void relaySignals(QXmppLoggable *from, QXmppLoggable *to)
{
    QObject::connect(from, SIGNAL(logMessage(QXmppLogger::MessageType,QString)),
                     to, SIGNAL(logMessage(QXmppLogger::MessageType,QString)));
    QObject::connect(from, SIGNAL(setGauge(QString,double)),
                     to, SIGNAL(setGauge(QString,double)));
    QObject::connect(from, SIGNAL(updateCounter(QString,qint64)),
                     to, SIGNAL(updateCounter(QString,qint64)));
}
/// Constructs a new QXmppLoggable.
///
/// param parent
QXmppLoggable::QXmppLoggable(QObject *parent)
    : QObject(parent)
{
    QXmppLoggable *logParent = qobject_cast<QXmppLoggable*>(parent);
    if (logParent) {
        relaySignals(this, logParent);
    }
}
/// cond
void QXmppLoggable::childEvent(QChildEvent *event)
{
    QXmppLoggable *child = qobject_cast<QXmppLoggable*>(event->child());
    if (!child)
        return;
    if (event->added()) {
        relaySignals(child, this);
    } else if (event->removed()) {
        disconnect(child, SIGNAL(logMessage(QXmppLogger::MessageType,QString)),
                this, SIGNAL(logMessage(QXmppLogger::MessageType,QString)));
        disconnect(child, SIGNAL(setGauge(QString,double)),
                this, SIGNAL(setGauge(QString,double)));
        disconnect(child, SIGNAL(updateCounter(QString,qint64)),
                this, SIGNAL(updateCounter(QString,qint64)));
    }
}
/// endcond
class QXmppLoggerPrivate
{
public:
    QXmppLoggerPrivate(QXmppLogger *qq);
    QXmppLogger::LoggingType loggingType;
    QFile *logFile;
    QString logFilePath;
    QXmppLogger::MessageTypes messageTypes;
private:
    QXmppLogger *q;
};
QXmppLoggerPrivate::QXmppLoggerPrivate(QXmppLogger *qq)
    : loggingType(QXmppLogger::NoLogging),
    logFile(0),
    logFilePath("QXmppClientLog.log"),
    messageTypes(QXmppLogger::AnyMessage),
    q(qq)
{
}
/// Constructs a new QXmppLogger.
///
/// param parent
QXmppLogger::QXmppLogger(QObject *parent)
    : QObject(parent)
{
    d = new QXmppLoggerPrivate(this);
    // make it possible to pass QXmppLogger::MessageType between threads
    qRegisterMetaType< QXmppLogger::MessageType >("QXmppLogger::MessageType");
}
QXmppLogger::~QXmppLogger()
{
    delete d;
}
/// Returns the default logger.
///
QXmppLogger* QXmppLogger::getLogger()
{
    if(!m_logger)
        m_logger = new QXmppLogger();
    return m_logger;
}
/// Returns the handler for logging messages.
///
QXmppLogger::LoggingType QXmppLogger::loggingType()
{
    return d->loggingType;
}
/// Sets the handler for logging messages.
///
/// param type
void QXmppLogger::setLoggingType(QXmppLogger::LoggingType type)
{
    if (d->loggingType != type) {
        d->loggingType = type;
        reopen();
    }
}
/// Returns the types of messages to log.
///
QXmppLogger::MessageTypes QXmppLogger::messageTypes()
{
    return d->messageTypes;
}
/// Sets the types of messages to log.
///
/// param types
void QXmppLogger::setMessageTypes(QXmppLogger::MessageTypes types)
{
    d->messageTypes = types;
}
/// Add a logging message.
///
/// param type
/// param text
void QXmppLogger::log(QXmppLogger::MessageType type, const QString& text)
{
    // filter messages
    if (!d->messageTypes.testFlag(type))
        return;
    switch(d->loggingType)
    {
    case QXmppLogger::FileLogging:
        if (!d->logFile) {
            d->logFile = new QFile(d->logFilePath);
            d->logFile->open(QIODevice::WriteOnly | QIODevice::Append);
        }
        QTextStream(d->logFile) << formatted(type, text) << "n";
        break;
    case QXmppLogger::StdoutLogging:
        std::cout << qPrintable(formatted(type, text)) << std::endl;
        break;
    case QXmppLogger::SignalLogging:
        emit message(type, text);
        break;
    default:
        break;
    }
}
/// Sets the given a gauge to a value.
///
/// NOTE: the base implementation does nothing.
void QXmppLogger::setGauge(const QString &gauge, double value)
{
    Q_UNUSED(gauge);
    Q_UNUSED(value);
}
/// Updates the given a counter by a amount.
///
/// NOTE: the base implementation does nothing.
void QXmppLogger::updateCounter(const QString &counter, qint64 amount)
{
    Q_UNUSED(counter);
    Q_UNUSED(amount);
}
/// Returns the path to which logging messages should be written.
///
/// sa loggingType()
QString QXmppLogger::logFilePath()
{
    return d->logFilePath;
}
/// Sets the path to which logging messages should be written.
///
/// param path
///
/// sa setLoggingType()
void QXmppLogger::setLogFilePath(const QString &path)
{
    if (d->logFilePath != path) {
        d->logFilePath = path;
        reopen();
    }
}
/// If logging to a file, causes the file to be re-opened.
///
void QXmppLogger::reopen()
{
    if (d->logFile) {
        delete d->logFile;
        d->logFile = 0;
    }
}

注意QXmppLogger::SignalLogging选项。如果设置了,对象将发出message(type, text);信号,而不是写入文件。您可以连接到此信号,并使用typetext执行任何您想要的操作。

最新更新