Russian Qt Forum
Ноябрь 23, 2024, 10:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Log4Qt - система ведения журналов сообщений за несколько минут  (Прочитано 26971 раз)
asvil
Гость
« : Апрель 19, 2010, 20:14 »

Авторство портирования данного проекта из log4j (http://logging.apache.org/log4j/) принадлежит человеку по имени Martin Heinrich. Подробнее о данном проекте http://log4qt.sourceforge.net.
Я в свою очередь перевел проект на CMake систему сборки, а также добавил несколько функций.
Кратко о возможностях:
  • Ведение нескольких журналов.
  • Форматирование сообщений.
  • Один и более методов вывода журнала:
    • файл
    • консоль
    • отладочный вывод
    • sql база данных
  • Перехват qDebug, qWarning, qCritical, QFatal
Направления вывода сообщений:


Быстрый старт требует от Вас наличия git'а и системы сборки cmake версии не ниже, чем 2.6.
Скачиваем архив главной ветки проекта:
Код:
http://gitorious.org/log4qt/log4qt/archive-tarball/master
Или клонируем репозиторий:
Код:
git clone git://gitorious.org/log4qt/log4qt.git
Далее:
*NIX
Код:
cd log4qt
cmake -DQT_USE_QTSQL=TRUE -DCMAKE_BUILD_TYPE=Release .
make
make install
WIN*
Код:
cd log4qt
cmake -DQT_USE_QTSQL=TRUE  -DCMAKE_BUILD_TYPE=Release -G "MinGW Makefiles" .
mingw32-make
mingw32-make install

После выше перечисленных манипуляций в зависимости от системы сборки необходимо добавить в файл Вашего проекта следующие строки:
qmake
Код:
CONFIG += log4qt 
cmake
Код:
find_package(log4qt PATHS ${QT_MKSPECS_DIR}/cmake NO_DEFAULT_PATH)
include_directories(${LOG4QT_INCLUDE_DIRS}) 
target_link_libraries(main ${QT_LIBRARIES} log4qt)

Использование в проекте:
Подключение заголовочных файлов:
Код:
#include <Log4Qt/logmanager.h>
#include <Log4Qt/simplelayout.h>
#include <Log4Qt/consoleappender.h>
#include <Log4Qt/databaselayout.h>
#include <Log4Qt/databaseappender.h>
#include <Log4Qt/ttcclayout.h>
#include <Log4Qt/consoleappender.h>
Весь ниже перечисленный код использует Log4Qt пространство имен:
Код:
using namespace Log4Qt;
[/b]
Загружаем файл перевода для библиотеки:
Код:
QTranslator trans;
trans.load("log4qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
app.installTranslator(&trans);
Инициализация главного журнала:
Код:
LogManager::rootLogger();
Перехват qDebug, qWarning...
Код:
LogManager::setHandleQtMessages(true);

Создание объекта, форматирующего сообщения в простом виде (тип, имя журнала, сообщение):
Код:
simpleLayout = new SimpleLayout();
simpleLayout->setName(QLatin1String("SimpleLayout"));

Каждый объект должен быть активирован.
Код:
simpleLayout->activateOptions();
Данный объект форматирует сообщение в строку содержащую все данные (дата/время, тип, имя журнала, поток, сообщение). В конструкторе задается формат вывода даты/времени.
Код:
TTCCLayout *ttccLayout = new TTCCLayout(TTCCLayout::ISO8601);
ttccLayout->setName(QLatin1String("TtccLayout"));
ttccLayout->activateOptions();
Создание объекта выводящего сообщения в консоль.
Данному объекту в конструкторе назначается объект форматирующий сообщения.
Код:
ConsoleAppender *consoleAppender = new ConsoleAppender(simpleLayout, ConsoleAppender::STDOUT_TARGET);
consoleAppender->setName(QLatin1String("ConsoleAppender"));
consoleAppender->activateOptions();

Создание объекта генерирующего сигнал при возникновении сообщения.
Код:
SignalAppender *signalAppeder = new SignalAppender();
signalAppeder->setName("SignalAppender");
Назначение объекта форматирующего сообщения.
Код:
signalAppeder->setLayout(ttccLayout);
signalAppeder->activateOptions();

Назначаем корневому журналу сообщений выводящие объекты:
Код:
LogManager::rootLogger()->addAppender(d->signalAppeder);
LogManager::rootLogger()->addAppender(d->consoleAppender);
В системе есть один корневой журнал в которые приходят все сгенерированные сообщения и любое число дочерних журналов, в которые приходят только те сообщения, которые туда и отправлялись:) Объект журнала создавать не нужно, он создается автоматически при первом к нему обращении, например:
Код:
LogManager::logger("SimpleLogger");
Создание системы ведения журнала сообщений в базе данных:
Где-то в дебрях исходных текстов:
Код:
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setDatabaseName("postgres");
db.open("postgres", "postgres"));
db.exec("CREATE TABLE log_table
(
  time_stamp timestamp without time zone,
  logger text,
  thread text,
  _level text,
  message text
)
WITH (
  OIDS=FALSE
);");
Инициализация форматирования и вывода сообщений в sql базу данных:
Код:
DatabaseLayout *dbLayout = new DatabaseLayout();
Назначаем соответсвтия между структурой сообщения и sql таблицей:
Код:
dbLayout->setTimeStampColumn("time_stamp");
dbLayout->setLoggerNameColumn("logger");
dbLayout->setThreadNameColumn("thread");
dbLayout->setLevelColumn("_level");
dbLayout->setMessageColumn("message");

Создаем объект вывода сообщений в базу данных. В конструкторе указывает имя таблицы, имя qt sql соединения.
Код:
DatabaseAppender *dbAppender = new DatabaseAppender(dbLayout, "log_table", db.connectionName());
dbAppender->setName(QLatin1String("DatabaseAppender"));
dbAppender->activateOptions();

Выводим журнал сообщений именуемый "Database" в базу данных, а также на консоль.
Код:
LogManager::logger("Database")->addAppender(dbAppender);
LogManager::logger("Database")->addAppender(consoleAppender);

Теперь где угодно в *.cpp, подключив Log4Qt/logmanager.h, оставляем о себе знать:
Код:
LogManager::logger("Database")->info("Message from " + Q_FUNC_INFO);
Данное сообщение попадет в журнал Database и в корневой журнал. Журнал Database выводиться в sql базу данных, а также в консоль. Корневой журнал выводится в консоль, а также генерируется сигнал, оповещающий о получении сообщения.

Создание вывода в файл. При достижении файлом определенного размера, будет выполняться его резервное копирование.
Код:
RollingFileAppender *dbFileAppender = new RollingFileAppender(ttccLayout,"myapp.log", true);
d->dbFileAppender->setName("FileAppender");
d->dbFileAppender->activateOptions();
d->dbFileAppender->setMaximumFileSize(1024*1024*10); // max file size 10 mb
LogManager::logger("FileLogger")->addAppender(dbFileAppender);

Кроме всеговышеперечисленного данные проект содержит возможность диамического создания журналов, объектов форматирования и вывода сообщений на основе QSettings. Но заглянув туда я увидел схему преобразования QSettings, грубо говоря, в log4j settings. Потом это log4j settings анализируется и с помощью фабрики классов создаются новые объекты. Q_INVOKABLE конструкторы не используются, что не очень удобно при создании новый классов вывода, форматирования сообщений. Вообщем на данную возможность ставку делать, на мой взгляд, не стоит.
А также я не затрагивал систему фильтрации сообщений.

P.S. Возможно я обманул Вас, в заголовке сообщения форума.
Записан
fland
Гость
« Ответ #1 : Апрель 20, 2010, 19:23 »

как я понял основоной плюс по сравнению с qDebug/qError/etc - более удобная работа с БД?
Записан
asvil
Гость
« Ответ #2 : Апрель 20, 2010, 22:56 »

Да вы правильно поняли. Смею поправить - скорее работа с БД просто есть. А используя без Log4Qt qDebug()... эту работу необходимо реализовывать.
К основным плюсам также можно отнести: детализированность сообщения (время, поток, журнал, уровень (info, warning, debug), наличие неограниченного числа журналов, которые могут выводиться каждый в своем "направлении" (БД, консоль, файл).
Работа с журналом сообщений сводится к нескольким действиям:
  • Открыть qt sql подключение
  • Создать Log4Qt::DatabaseLayout
  • Назначить соответствия имен столбцов с полями сообщения
Код:
Log4Qt::DatabaseLayout::set*Column(columnName);

  • Создать Log4Qt::DatabaseAppender
  • Назначить qt sql подключение и имя таблицы
Код:
Log4Qt::DatabaseAppender::setConnection(connectionName);
Log4Qt::DatabaseAppender::setTable(tableName);

  • Применить созданный объект вывода (Log4Qt::DatabaseAppender) к любому журналу, получаемому вызовом:
Код:
Log4Qt::LogManager::logger(loggerName)::addAppender()
или же корневому журналу, куда попадают все сообщения генерируемые в приложении:
Код:
Log4Qt::LogManager::rootLogger()::addAppender()
    После чего все qDebug() заменить на
    Код:
    Log4Qt::LogManager::logger("Имя подпроекта")->debug(QString("%1 - %2").arg(Q_FUNC_INFO,"исходное сообщение"))
    все qWarning() на
    Код:
    Log4Qt::LogManager::logger("Имя подпроекта")->warn(QString("%1 - %2").arg(Q_FUNC_INFO,"исходное сообщение"))
    И т.д.
    Записан
    lit-uriy
    Джедай : наставник для всех
    *******
    Offline Offline

    Сообщений: 3880


    Просмотр профиля WWW
    « Ответ #3 : Апрель 20, 2010, 23:35 »

    а при задании размер журнала библиотека будет заниматься урезанием наиболее старых сообщений, а не всех?
    Записан

    Юра.
    SABROG
    Гость
    « Ответ #4 : Апрель 20, 2010, 23:50 »

    Код
    C++ (Qt)
    Log4Qt::LogManager::logger("Имя подпроекта")->debug(QString("%1 - %2").arg(Q_FUNC_INFO,"исходное сообщение"))

    Длинновато Улыбающийся

    Судя по всему вся прелесть перегруженности оператора << теряется и придется всё писать самому. Например вывод имен установленных флагов, названий перечислений, содержимое контейнеров...
    Записан
    asvil
    Гость
    « Ответ #5 : Апрель 21, 2010, 09:19 »

    а при задании размер журнала библиотека будет заниматься урезанием наиболее старых сообщений, а не всех?
    По логике проекта данной функцией должен заниматься выводящий объект (Log4Qt::*Appender). *RollingFileAppender реализовывают резервное копирование более ранних сообщений в отдельный файл.
    В DatabaseAppender я не реализовал данную функцию. Проблема заключается в том, что по усмотрению программиста, DatabaseLayout может не соотносить дату/время сообщения с колонкой таблицы, и соответственно дата/время сохраняться не будет. Поэтому удалить ранее внесенные записи в таблице я не могу. Так как я пользуюсь postgresql, то при необходимости, скорее реализую данную функцию в триггере. Если sql-путь решения проблемы не удобен, я могу назначить "обязательное" соотнесение столбца для даты и поля сообщения журнала, а также создать RollingDatabaseAppender, где в зависимости от количество строк в таблице, будут удаляться более ранние по дате/времени сообщения.

    Цитата: SABROG
    Длинновато
    Не могу не согласиться. Для того, чтобы сохранить возможности перегруженных операторов "QDebug() <<", библиотекой регистрируется "перехватчик" данных сообщений. Для этого в инициализационной части Вашего проекта необходимо вызвать:
    Код:
    Log4Qt::LogManager::setHandleQtMessages(true);
    В результате qDebug() и др. будут перенаправляться в журнал с именем Qt. Доступ к этому журналу можно получить данной строкой:
    Код:
     Log4Qt::LogManager::qtLogger()
    Данный журнал как и любой другой можно направить в интересующем из доступных направлений. На будущее скажу что реализация класса, выводящего сообщения сводится к переопределению одного метода. В библиотеке имеется TextAppender, который выводит сообщения в QTextStream, что позволяет назначить свой поток вывода, унаследованный от вышеназванного класса.
    Я умалчиваю о классе форматирующем сообщения в зависимости от строки-шаблона Log4Qt::PatternLayout. У меня не дошли до него руки. А если быть точнее, что-то в нем не заработало с первого раза, и я перенес свое внимание на другие проблемы.
    « Последнее редактирование: Апрель 21, 2010, 10:42 от asvil » Записан
    SABROG
    Гость
    « Ответ #6 : Апрель 21, 2010, 09:53 »

    А это уже интересно. Планируется ли в Log4Qt добавить "цветной" вывод логов в консоль (как в CMake)? Где-то уже на этом форуме поднималась тема как это реализовать для Windows и Linux.
    Записан
    kuzulis
    Джедай : наставник для всех
    *******
    Offline Offline

    Сообщений: 2812


    Просмотр профиля
    « Ответ #7 : Апрель 21, 2010, 11:02 »

    Цитировать
    А это уже интересно. Планируется ли в Log4Qt добавить "цветной" вывод логов в консоль (как в CMake)? Где-то уже на этом форуме поднималась тема как это реализовать для Windows и Linux.
    дадада, и чтобы можно выло устанавливать любой цвет на любые типы сообщений!
    Записан

    ArchLinux x86_64 / Win10 64 bit
    asvil
    Гость
    « Ответ #8 : Апрель 21, 2010, 15:56 »

    Я не нуждаюсь в цветном выводе в консоль, так как я пользуюсь выводом "в сигнал", и в последствии вывожу в QPlainTextEdit. При выводе в QPlainTextEdit я задаю цвет.
    Я читал "цветной вывод", и на основе некоторых сообщений сделал выводящий класс, унаследованный от Log4Qt::ConsoleAppender. Не придумав ничего лучше, я реализовал цветной вывод в зависимости от регулярного выражения сравниваемого с уже отформатированным сообщением. Я решил, что если сделаю что-то с более сложным интерфейсом, где для каждого составляющей сообщения будет назначаться свой цвет, то мощность и сложность использования такого решения будет излишней для цели.
    Проблема, с которой я столкнулся, заключается в том, что в Ubuntu 9.10, я не смог назначить background color. А также я прошу заинтересовавшихся протестировать класс в win среде.

    Использование цветного вывода сводится к нескольким шагам.
    • Создать объект форматирующий сообщения
    • Создать объект выводящий сообщения в цвете
    • Создать карту цветов. Карта цветов - это: QHash<QString, QPair<int, int> >. Где QString используется в качество шаблона для QRegExp, QPair::first является цветом шрифта, QPair::second - background color.Например:
    Код:
    ColorConsoleAppender::ColorMap colorMap;
    colorMap[".*Qt.*"] = QPair<int,int>(ColorConsoleAppender::ForegroundLightGreen, ColorConsoleAppender::BackgroundBlue);
    colorMap[".*INFO.*Logger - .*"] = QPair<int,int>(ColorConsoleAppender::ForegroundLightGreen, ColorConsoleAppender::BackgroundBlue);
    colorMap[".*WARN.*Logger.*"] = QPair<int,int>(ColorConsoleAppender::ForegroundLightRed, ColorConsoleAppender::BackgroundBlue);
    • Назначить объекту выводящему сообщения карту цветов. Для этого служит функция:
    Код:
    Log4Qt::ColorConsoleAppender::setColorMap()
    • Назначить получившийся объект вывода, любому понравившемуся журналу с помощью:
    Код:
    Log4Qt::LogManager::logger()::addAppender()

      Заголовочный файл colorconsoleappender.h
      Код:
      /******************************************************************************
       *
       * package:     log4qt
       * file:        colorconsoleappender.h
       * created:     March 2010
       * author:      Filonenko Michael
       *
       *
       * Copyright 2010 Filonenko Michael
       *
       * Licensed under the Apache License, Version 2.0 (the "License");
       * you may not use this file except in compliance with the License.
       * You may obtain a copy of the License at
       *
       *     http://www.apache.org/licenses/LICENSE-2.0
       *
       * Unless required by applicable law or agreed to in writing, software
       * distributed under the License is distributed on an "AS IS" BASIS,
       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       * See the License for the specific language governing permissions and
       * limitations under the License.
       *
       ******************************************************************************/

      #ifndef _COLORCONSOLEAPPENDER_H
      #define _COLORCONSOLEAPPENDER_H


      /******************************************************************************
       * Dependencies
       ******************************************************************************/

      #include "consoleappender.h"

      #include <QtCore/QHash>
      #include <QtCore/QPair>
      #include <QtCore/QRegExp>


      /******************************************************************************
       * Declarations
       ******************************************************************************/

      class QFile;
      class QTextStream;

      namespace Log4Qt
      {

      /*!
      * \brief The class ConsoleAppender appends to stdout or stderr.
      *
      * \note All the functions declared in this class are thread-safe.
      *
      * \note The ownership and lifetime of objects of this class are managed.
      *       See \ref Ownership "Object ownership" for more details.
      */
      class LOG4QT_EXPORT  ColorConsoleAppender : public ConsoleAppender
      {
      Q_OBJECT

      Q_ENUMS(ForegroundColor BackgroundColor Colors)

      public:
      typedef QHash<QString, QPair<int, int> > ColorMap;
      #if defined(linux) || defined(__linux) || defined(__linux__) || defined(Q_OS_UNIX)
      enum ForegroundColor {
      ForegroundLightBlack = 30
      , ForegroundLightRed = 31
      , ForegroundLightGreen = 32
      , ForegroundLightYellow = 33
      , ForegroundLightBlue = 34
      , ForegroundLightPurple = 35
      , ForegroundLightCyan = 36
      , ForegroundLightWhite = 37
      };

      enum BackgroundColor {
      BackgroundBlack = 40
      , BackgroundRed = 41
      , BackgroundGreen   = 42
      , BackgroundYellow  = 43
      , BackgroundBlue    = 44
      , BackgroundPurple  = 45
      , BackgroundCyan    = 46
      , BackgroundWhite   = 47
      };

      enum Colors {
      Default = 0
      , Bright = 1
      , Blink = 5
      };
      #endif

      #if defined(__WIN32__) || defined(WIN) || defined(WIN32) || defined(Q_OS_WIN32)
      enum ForegroundColor {
      ForegroundLightBlack  = 0
      , ForegroundLightRed    = 4
      , ForegroundLightGreen  = 2
      , ForegroundLightYellow = 14
      , ForegroundLightBlue   = 1
      , ForegroundLightPurple = 5
      , ForegroundLightCyan   = 11
      , ForegroundLightWhite  = 15
      };

      enum BackgroundColor {
      BackgroundBlack    = 0
      , BackgroundRed   = 4
      , BackgroundGreen   = 2
      , BackgroundYellow  = 14
      , BackgroundBlue    = 1
      , BackgroundPurple  = 5
      , BackgroundCyan    = 11
      , BackgroundWhite   = 15
      };

      enum Colors {
      Default = 0
      , Bright = +8
      , Blink = 6
      };
      #endif
      ColorConsoleAppender(QObject *pParent = 0);
      ColorConsoleAppender(Layout *pLayout,
      QObject *pParent = 0);
      ColorConsoleAppender(Layout *pLayout,
      const QString &rTarget,
      QObject *pParent = 0);

      /*!
      * Creates a ConsoleAppender with the layout \a pLayout, the target
      * value specified by the \a target constant and the parent
      * \a pParent.
      */
      ColorConsoleAppender(Layout *pLayout,
      Target target,
      QObject *pParent = 0);

      void setColorMap(const ColorMap& map);

      protected:
      virtual void append(const LoggingEvent& rEvent);

      private:
      ColorMap colorMap;
      };

      /**************************************************************************
      * Operators, Helper
      **************************************************************************/


      /**************************************************************************
      * Inline
      **************************************************************************/

      } // namespace Log4Qt

      // Q_DECLARE_TYPEINFO(::ConsoleAppender, Q_COMPLEX_TYPE); // Use default


      #endif // _COLORCONSOLEAPPENDER_H

      Файл с реализацией класса colorconsoleappender.cpp:
      Код:
      /******************************************************************************
       *
       * package: log4qt
       * file:        colorconsoleappender.cpp
       * created:     March 2010
       * author:      Filonenko Michael
       *
       *
       * Copyright 2010 Filonenko Michael
       *
       * Licensed under the Apache License, Version 2.0 (the "License");
       * you may not use this file except in compliance with the License.
       * You may obtain a copy of the License at
       *
       *     http://www.apache.org/licenses/LICENSE-2.0
       *
       * Unless required by applicable law or agreed to in writing, software
       * distributed under the License is distributed on an "AS IS" BASIS,
       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       * See the License for the specific language governing permissions and
       * limitations under the License.
       *
       ******************************************************************************/

      /******************************************************************************
       * Dependencies
       ******************************************************************************/


      #include "colorconsoleappender.h"

      #include <QtCore/QTextStream>

      #include <Log4Qt/loggingevent.h>
      #include <Log4Qt/layout.h>
      #include <Log4Qt/helpers/datetime.h>

      #if defined(__WIN32__) || defined(WIN) || defined(WIN32) || defined(Q_OS_WIN32)
      #include <windows.h>
      #endif

      namespace Log4Qt
      {


      /**************************************************************************
      * Declarations
      **************************************************************************/



      /**************************************************************************
      * C helper functions
      **************************************************************************/



      /**************************************************************************
      * Class implementation: ColorConsoleAppender
      **************************************************************************/


      ColorConsoleAppender::ColorConsoleAppender(QObject *pParent) :
      ConsoleAppender(pParent)
      {
      }


      ColorConsoleAppender::ColorConsoleAppender(Layout *pLayout,
      QObject *pParent) :
      ConsoleAppender(pLayout, pParent)
      {
      }


      ColorConsoleAppender::ColorConsoleAppender(Layout *pLayout,
      const QString &rTarget,
      QObject *pParent) :
      ConsoleAppender(pLayout, rTarget, pParent)
      {}


      ColorConsoleAppender::ColorConsoleAppender(Layout *pLayout,
      Target target,
      QObject *pParent) :
      ConsoleAppender(pLayout, target, pParent)
      {
      }


      void ColorConsoleAppender::append(const LoggingEvent &rEvent)
      {

      // форматируем собщение
      QString message = layout()->format(rEvent);

      QRegExp rexp;

      // if we are in win*
      #if defined(__WIN32__) || defined(WIN) || defined(WIN32) || defined(Q_OS_WIN32)
      // Getting pointer to console
      HANDLE  hConsole;
      if (target() == "STDOUT_TARGET")
      hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
      else if (target() == "STDERR_TARGET")
      hConsole = GetStdHandle(STD_ERROR_HANDLE);

      // save colors
      CONSOLE_SCREEN_BUFFER_INFO cbi = {sizeof(cbi)};
      GetConsoleScreenBufferInfo(hConsole,&cbi);

      ColorMap::ConstIterator colorMapIt = colorMap.constBegin();
      ColorMap::ConstIterator colorMapEnd = colorMap.constEnd();

      for(;colorMapIt != colorMapEnd; ++colorMapIt) {
      rexp.setPattern(colorMapIt.key());
      if (rexp.exactMatch(message)) {
      // load colors
      SetConsoleTextAttribute(hConsole, colorMapIt.value().second*16
      + colorMapIt.value().first);
      break;
      }
      }

      // print message to output console
      writer()->operator <<(message);

      // load old colors
      SetConsoleTextAttribute(hConsole, cbi.wAttributes);
      #endif // #if defined(__WIN32__) || defined(WIN) || defined(WIN32) || defined(Q_OS_WIN32)

      // if we are in *nix
      #if defined(linux) || defined(__linux) || defined(__linux__) || defined(Q_OS_UNIX)

      ColorMap::ConstIterator colorMapIt = colorMap.constBegin();
      ColorMap::ConstIterator colorMapEnd = colorMap.constEnd();

      for(;colorMapIt != colorMapEnd; ++colorMapIt) {
      rexp.setPattern(colorMapIt.key());
      if (rexp.exactMatch(message)) {
      message.prepend(QString("\e[%1m").arg(QString::number(colorMapIt.value().first)));
      message.append("\e[0m");
      break;
      }
      }

      writer()->operator <<(message);

      #endif //#if defined(linux) || defined(__linux) || defined(__linux__) || defined(Q_OS_UNIX)

      // обрабатываем ошибки, по умолчанию метод не реализован
      if (handleIoErrors())
      return;

      if (immediateFlush())
      {
      writer()->flush();
      if (handleIoErrors())
      return;
      }
      }

      void ColorConsoleAppender::setColorMap(const ColorMap& map)
      {
      colorMap = map;
      }

      /******************************************************************************
      * Implementation: Operators, Helper
      ******************************************************************************/


      } // namespace Log4Qt

      Использование в проекте:
      Код:
      #include "colorconsoleappender.h"
      .............................

      SimpleTimeLayout *timeLayout = new SimpleTimeLayout();
      timeLayout->setName("TimeLayout");
      timeLayout->activateOptions();

      ColorConsoleAppender *colorAppender = new ColorConsoleAppender(timeLayout, ColorConsoleAppender::STDOUT_TARGET);
      colorAppender->setName("ColorAppender");
      colorAppender->activateOptions();

      ColorConsoleAppender::ColorMap colorMap;
      colorMap[".*Qt.*"] = QPair<int,int>(ColorConsoleAppender::ForegroundLightGreen, ColorConsoleAppender::BackgroundBlue);
      colorMap[".*INFO.*Logger - .*"] = QPair<int,int>(ColorConsoleAppender::ForegroundLightGreen, ColorConsoleAppender::BackgroundBlue);
      colorMap[".*WARN.*Logger.*"] = QPair<int,int>(ColorConsoleAppender::ForegroundLightRed, ColorConsoleAppender::BackgroundBlue);
      colorAppender->setColorMap(colorMap);

      LogManager::rootLogger()->addAppender(colorAppender);
      LogManager::rootLogger();
      qDebug() << "From qDebug() ";

      LogManager::logger("Logger")->info("First message");

      LogManager::logger("Logger")->warn("Warn message");

      LogManager::logger("SecondLogger")->warn("Second message");
      Записан
      asvil
      Гость
      « Ответ #9 : Апрель 21, 2010, 15:58 »

      Проект ColorConsoleAppender, использующий CMake >= 2.6.
      Записан
      SABROG
      Гость
      « Ответ #10 : Апрель 21, 2010, 16:41 »

      Чего-то не могу собрать:

      Код:
      [ 75%] Building CXX object CMakeFiles/main.dir/colorconsoleappender.cpp.obj
      c:\mingw\bin\g++.exe   -DQT_DLL -DQT_GUI_LIB -DQT_SQL_LIB -DQT_CORE_LIB -DQT_DEBUG -g -IC:\SABROG\colorappender -IC:\SABROG\qt-everywhere-opensource-src-4.6.2\include -IC:\SABROG\qt-everywhere-opensource-src-4.6.2\include\QtGui -IC:\SABROG\
      qt-everywhere-opensource-src-4.6.2\include\QtSql -IC:\SABROG\qt-everywhere-opensource-src-4.6.2\include\QtCore -IC:\SABROG\qt-everywhere-opensource-src-4.6.2\include\Log4Qt   -o CMakeFiles\main.dir\colorconsoleappender.cpp.obj -c C:\SABROG\colorappender\colorconsoleappender.cpp
      C:\SABROG\colorappender\colorconsoleappender.cpp:63: warning: 'Log4Qt::ColorConsoleAppender::ColorConsoleAppender(QObject*)' redeclared without dllimport attribute: previous dllimport ignored
      C:\SABROG\colorappender\colorconsoleappender.cpp:69: warning: 'Log4Qt::ColorConsoleAppender::ColorConsoleAppender(Log4Qt::Layout*, QObject*)' redeclared without dllimport attribute: previous dllimport ignored
      C:\SABROG\colorappender\colorconsoleappender.cpp:76: warning: 'Log4Qt::ColorConsoleAppender::ColorConsoleAppender(Log4Qt::Layout*, const QString&, QObject*)' redeclared without dllimport attribute: previous dllimport ignored
      C:\SABROG\colorappender\colorconsoleappender.cpp:83: warning: 'Log4Qt::ColorConsoleAppender::ColorConsoleAppender(Log4Qt::Layout*, Log4Qt::ConsoleAppender::Target, QObject*)' redeclared without dllimport attribute: previous dllimport ignored
      C:\SABROG\colorappender\colorconsoleappender.cpp:91: warning: 'virtual void Log4Qt::ColorConsoleAppender::append(const Log4Qt::LoggingEvent&)' redeclared without dllimport attribute: previous dllimport ignored
      C:\SABROG\colorappender\colorconsoleappender.cpp:163: warning: 'void Log4Qt::ColorConsoleAppender::setColorMap(const QHash<QString, QPair<int, int> >&)' redeclared without dllimport attribute: previous dllimport ignored
      C:\CMake\bin\cmake.exe -E cmake_progress_report C:\SABROG\colorappender\CMakeFiles 3
      [100%] Building CXX object CMakeFiles/main.dir/moc_colorconsoleappender.cxx.obj
      c:\mingw\bin\g++.exe   -DQT_DLL -DQT_GUI_LIB -DQT_SQL_LIB -DQT_CORE_LIB -DQT_DEBUG -g -IC:\SABROG\colorappender -IC:\SABROG\qt-everywhere-opensource-src-4.6.2\include -IC:\SABROG\qt-everywhere-opensource-src-4.6.2\include\QtGui -IC:\SABROG\
      qt-everywhere-opensource-src-4.6.2\include\QtSql -IC:\SABROG\qt-everywhere-opensource-src-4.6.2\include\QtCore -IC:\SABROG\qt-everywhere-opensource-src-4.6.2\include\Log4Qt   -o CMakeFiles\main.dir\moc_colorconsoleappender.cxx.obj -c C:\SABROG\colorappender\moc_colorconsoleappender.cxx
      C:\SABROG\colorappender\moc_colorconsoleappender.cxx:76: warning: 'Log4Qt::ColorConsoleAppender::staticMetaObject' redeclared without dllimport attribute afterbeing referenced with dll linkage
      C:\SABROG\colorappender\moc_colorconsoleappender.cxx:85: warning: 'virtual const
       QMetaObject* Log4Qt::ColorConsoleAppender::metaObject() const' redeclared without dllimport attribute: previous dllimport ignored
      C:\SABROG\colorappender\moc_colorconsoleappender.cxx:90: warning: 'virtual void*
       Log4Qt::ColorConsoleAppender::qt_metacast(const char*)' redeclared without dllimport attribute: previous dllimport ignored
      C:\SABROG\colorappender\moc_colorconsoleappender.cxx:98: warning: 'virtual int Log4Qt::ColorConsoleAppender::qt_metacall(QMetaObject::Call, int, void**)' redeclared without dllimport attribute: previous dllimport ignored
      Linking CXX executable main.exe
      C:\CMake\bin\cmake.exe -E cmake_link_script CMakeFiles\main.dir\link.txt --verbose=1
      c:\mingw\bin\g++.exe  -g   CMakeFiles\main.dir\main.cpp.obj CMakeFiles\main.dir\colorconsoleappender.cpp.obj CMakeFiles\main.dir\moc_colorconsoleappender.cxx.obj  -o main.exe -Wl,--out-implib,libmain.dll.a -Wl,--major-image-version,0,--minor-image-version,0  C:\SABROG\qt-everywhere-opensource-src-4.6.2\lib\libQtGuid4.a
       C:\SABROG\qt-everywhere-opensource-src-4.6.2\lib\libQtSqld4.a C:\SABROG\qt-everywhere-opensource-src-4.6.2\lib\libQtCored4.a C:\SABROG\qt-everywhere-opensource-src-4.6.2\lib\liblog4qt.dll.a C:\SABROG\qt-everywhere-opensource-src-4.6.2\lib\libQtGui4.a C:\SABROG\qt-everywhere-opensource-src-4.6.2\lib\libQtSql4.a C:\SABROG\qt-everywhere-opensource-src-4.6.2\lib\libQtCore4.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32
      CMakeFiles\main.dir\main.cpp.obj: In function `main':
      C:/SABROG/colorappender/main.cpp:42: undefined reference to `_imp___ZN6Log4Qt20ColorConsoleAppenderC1EPNS_6LayoutENS_15ConsoleAppender6TargetEP7QObject'
      C:/SABROG/colorappender/main.cpp:53: undefined reference to `_imp___ZN6Log4Qt20ColorConsoleAppender11setColorMapERK5QHashI7QString5QPairIiiEE'
      CMakeFiles\main.dir\colorconsoleappender.cpp.obj: In function `ColorConsoleAppender':
      C:/SABROG/colorappender/colorconsoleappender.cpp:64: undefined reference to `_imp___ZTVN6Log4Qt20ColorConsoleAppenderE'
      C:/SABROG/colorappender/colorconsoleappender.cpp:64: undefined reference to `_imp___ZTVN6Log4Qt20ColorConsoleAppenderE'
      C:/SABROG/colorappender/colorconsoleappender.cpp:71: undefined reference to `_imp___ZTVN6Log4Qt20ColorConsoleAppenderE'
      C:/SABROG/colorappender/colorconsoleappender.cpp:71: undefined reference to `_imp___ZTVN6Log4Qt20ColorConsoleAppenderE'
      C:/SABROG/colorappender/colorconsoleappender.cpp:79: undefined reference to `_imp___ZTVN6Log4Qt20ColorConsoleAppenderE'
      CMakeFiles\main.dir\colorconsoleappender.cpp.obj:C:/SABROG/colorappender/colorconsoleappender.cpp:79: more undefined references to `_imp___ZTVN6Log4Qt20ColorConsoleAppenderE' follow
      CMakeFiles\main.dir\moc_colorconsoleappender.cxx.obj:C:/SABROG/colorappender/moc_colorconsoleappender.cxx:87: undefined reference to `_imp___ZN6Log4Qt20ColorConsoleAppender16staticMetaObjectE'
      CMakeFiles\main.dir\moc_colorconsoleappender.cxx.obj: In function `_static_initialization_and_destruction_0':
      C:/SABROG/colorappender/moc_colorconsoleappender.cxx:79: undefined reference to`_imp___ZN6Log4Qt20ColorConsoleAppender16staticMetaObjectE'
      collect2: ld returned 1 exit status
      mingw32-make[2]: *** [main.exe] Error 1
      mingw32-make[2]: Leaving directory `C:/SABROG/colorappender'
      mingw32-make[1]: *** [CMakeFiles/main.dir/all] Error 2
      mingw32-make[1]: Leaving directory `C:/SABROG/colorappender'
      mingw32-make: *** [all] Error 2
      « Последнее редактирование: Апрель 21, 2010, 17:21 от SABROG » Записан
      asvil
      Гость
      « Ответ #11 : Апрель 21, 2010, 19:52 »

      Прошу прощения, ориентировался на включение класса в "коробку". Необходимо удалить LOG4QT_EXPORT в определении класса:
      Код:
      class LOG4QT_EXPORT  ColorConsoleAppender : public ConsoleAppender
      Записан
      Prm
      Гость
      « Ответ #12 : Апрель 22, 2010, 08:00 »

      Еще было бы неплохо добавить уровни отладки(журналирования). Т.е. настроить систему журналов так, чтобы в нее попадали сообщения с уровнем <= требуемый.

      Например, пусть имеется 3 уровня отладки:
      0 - высший приоритет (для критических сообщений)
      1 - средний приоритет (обычные сообщения)
      2 - низший приоритет

      Пример использования:
      Пусть имеется объект работы с последовательным (ну или любым другим) портом. Информацию о событиях типа порт открыт/закрыт можно добавлять в журнал со средним приоритетом, распечатку принятых/отправляемых данных добавлять с низшим приоритетом.
      В процессе разработки объекта систему журналирования настраиваем на низший уровень приорита, видим полную картину работы объекта. Отладили программу - выставляем средний уровень и контролируем лишь основные события.


      Кроме того, может быть полезен TCP лог (часто им пользуюсь), т.к. не всегда удобно в реал-тайме осуществлять работу с программой и контролировать ее текущее состояние (модальные окна могут перекрывать отладочный лог). А так прога работает, отладочные сообщения через сокеты отправляются в другую прогу, которая их отображает.



      Записан
      asvil
      Гость
      « Ответ #13 : Апрель 22, 2010, 10:16 »

      Уровни отладки сообщений уже имеются, просто не были освещены мной.

      Первый путь использования:
      Порядок уровней сообщений:
      Код:
      enum Value
      {
      /*! NULL_INT is used for no level has been specified */
      NULL_INT = 0,
      ALL_INT = 32,
      TRACE_INT = 64,
      DEBUG_INT = 96,   // qDebug()
      INFO_INT = 128,    
      WARN_INT = 150,   // qWarning()
      ERROR_INT = 182,  // qCritical()
      FATAL_INT = 214,    // qFatal()
      OFF_INT = 255
      };
      Код:
      LogManager::logger("Logger")->setLevel(Level(Level::INFO_INT));
      После данной строки в журнал "Logger" будут попадать только сообщения НИЖЕ (или большие по значению) данного включительно, т.е. INFO, WARN, ERROR, FATAL.

      Второй путь использования более глобальный, применяется для всех журналов:
      Код:
      Log4Qt::LogManager::setTreshold(Level);
      Действие данной функции аналогично действию вышеназванной. В журналах будут регистрироваться только сообщения НИЖЕ (или большие по значению) установленного уровня включительно.

      Третий путь самый локальный: установка уровня сообщений для выводящего объекта:
      Код:
      Log4Qt::*Appender::setThreshold(Level)

      Prm, я надеюсь, что Вам подходят данные функции.

      Еще один путь взаимодействия с уровнями сообщений:
      • Создание объекта фильтрующего сообщения по уровню
      • Настройка объекта
      • Установка данного объекта в качестве фильтра в объект выводящий сообщения
      В выбранном направлении будут выводиться отфильтрованные сообщения. На данный момент существует два класса фильтрующих по уровню: LevelMatchFilter и LevelRangeFilter. Названия говорят сами за себя. Допустим есть задача не выводить сообщения отладочного типа:
      Код:
      // фильтр
      LevelMatchFilter *filter = new LevelMatchFilter();
      // не принимать сообщения
      filter->setAcceptOnMatch(false);
      // с данным уровнем
      filter->setLevelToMatch(Level(Level::DEBUG_INT));
      //filter->activateOptions(); // не требуется

      // добавляем фильтр объекту
      colorAppender->addFilter(filter);
      После данных манипуляций сообщения отладочного уровня выводиться с помощью colorAppender не будут.
      « Последнее редактирование: Апрель 22, 2010, 11:01 от asvil » Записан
      SABROG
      Гость
      « Ответ #14 : Апрель 22, 2010, 11:46 »

      Чего-то я понять не могу этот CMake. Даю команду:

      Код:
      cmake -DQT_USE_QTSQL=TRUE -DCMAKE_BUILD_TYPE=Release -G"MinGW Makefiles"
      mingw32-make

      На выходе получается .exe'шник требующий debug версии Qt'шных библиотек, в то время как liblog4qt.dll требует релизных.
      ---
      Понял, кое-кто жестко задал тип билда, так что он даже не переопределяется...
      Код:
      set(CMAKE_BUILD_TYPE Debug)
      ---
      Не  работают цвета в виндовой консоли:



      Ни когда запускаешь командой, ни когда двойным кликом на .exe'шник.
      « Последнее редактирование: Апрель 22, 2010, 11:56 от SABROG » Записан
      Страниц: [1] 2   Вверх
        Печать  
       
      Перейти в:  


      Страница сгенерирована за 0.083 секунд. Запросов: 23.