quarta-feira, 15 de fevereiro de 2012

Qt mensagens de log


A Qt fornece algumas funções de log úteis como a qDebug(), qWarning(), qCritical() e qFatal() mas em alguns casos precisamos mais do que simplesmente exibir mensagens na saída padrão, precisamos gravar essas mensagens em arquivos para que posteriormente possamos analisar a sua origem.

A própria API já fornece uma maneira simples de fazer isso, pelo uso do manipulador qInstallMsgHandler, com ele é possível capturar essas mensagens e tratá-las da maneira que mais lhe agrada.


class ArquivoLog
{
    QFile arquivo;
    QTextStream stream;

public:
    explicit ArquivoLog( QString nome )
        : arquivo(nome)
        , stream(&arquivo)
    {
        if (!(arquivo.open(QIODevice::WriteOnly | QIODevice::Append)))
            std::cerr << "Falha ao abrir o arquivo " << nome.toUtf8().data();
    }

    ~ArquivoLog()
    {
        //qDebug() << "~ArquivoLog()";
        stream.flush();
        arquivo.close();
    }

    QTextStream &Stream()
    {
        return stream;
    }
} log("main.log");


void MessageHandler(QtMsgType type, const char *msg)
{
    QString txt;
    switch (type)
    {
    case QtDebugMsg:
        txt = QString("[Debug    : %1] %2").arg(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss"), msg);
        #ifdef QT_DEBUG
            std::cout << txt.toUtf8().data() << std::endl;
        #endif
        break;
    case QtWarningMsg:
        txt = QString("[Warning  : %1] %2").arg(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss"), msg);
        #ifdef QT_DEBUG
            std::cerr << txt.toUtf8().data() << std::endl;
        #endif
        break;
    case QtCriticalMsg:
        txt = QString("[Critical : %1] %2").arg(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss"), msg);
        #ifdef QT_DEBUG
            std::cerr << txt.toUtf8().data() << std::endl;
        #endif
        break;
    case QtFatalMsg:
        txt = QString("[Fatal    : %1] %2").arg(QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss"), msg);
        #ifdef QT_DEBUG
            std::cerr << txt.toUtf8().data() << std::endl;
        #endif
    }
    log.Stream() << txt << endl;
}

int main(int , char**)
{
    qInstallMsgHandler(MessageHandler); // registramos o manipulador

    for (long int x = 0; x < 10; x++ )
        qDebug() << "qInstallMsgHandler";

    return 0;
}

Repare que o manipulador que registramos recebe um parâmetro enumerado do tipo QtMsgType com ele podemos identificar o tipo de mensagem, nos permitindo gravar os erros em arquivos diferentes conforme o tipo ou até mesmo os enviar através de sockets ou usando um web service com REST.

Nenhum comentário:

Postar um comentário