Russian Qt Forum

Qt => Общие вопросы => Тема начата: QuAzI от Март 29, 2012, 09:46



Название: Кроссплатформенное логирование
Отправлено: QuAzI от Март 29, 2012, 09:46
Что-то я трепыхался, трепыхался, да и задумался. А как народ хранит логи? Есть что-то для логирования, отдающее пути в духе QSettings (http://www.prog.org.ru/topic_21352_0.html) ?
Вариантов то собственно не много:
1) Хранить логи с приложением, как у меня пока что и сделано
Код:
    QFileInfo fi(qApp->applicationFilePath());
    QString filename( fi.absolutePath() +"/"+ fi.baseName()+".log" );
Но это не правильно
2) Хранить логи в /var/log, /var/tmp и на винде в %TEMP%, там и так мусорка, потом краёв не найдёшь, особенно в многопользовательских системах.
3) Хранить логи в пользовательской директории, с конфигом. ИМХО, самый правильный вариант, только не соображу, как правильно имя определить, не создавая заранее QSettings. Пути для логов и перенаправление qDebug через qInstallMsgHandler() у меня делается в main, а конфиг раньше вызова основной формы не нужен.

А как опытный народ делает?
И чтобы не плодить мусор: а куда вы QM-файлы кидаете и прочие ресурсы? На юнихах их держать в директории приложения тоже не принято.


Название: Re: Кроссплатформенное логирование
Отправлено: Пантер от Март 29, 2012, 09:48
Я рядышком обычно храню.


Название: Re: Кроссплатформенное логирование
Отправлено: QuAzI от Март 30, 2012, 12:56
В общем ничего умнее такого выброса для ресурсов я не нашёл
Код:
static inline QString getDefaultResourcePath()
{
#if defined Q_OS_WIN
    return qApp->applicationDirPath();
#elif defined Q_OS_MACX
    return ("/Resources");
#elif defined Q_OS_UNIX // not Mac UNIXes
    return (QStiring('/usr/local/share/') + qApp->applicationName());
#endif
}
Дальше уже для переводов дёргать что-то вида
QString localeFile = getDefaultResourcePath() + '/translations/'  + QLocale::system().name()

Но это прокатит только если qApp проинициализирован. Чем бы его подменить для нормального получения путей в консольках/библиотеках(плагинах)?


Название: Re: Кроссплатформенное логирование
Отправлено: QuAzI от Март 30, 2012, 13:01
Логи решил кидать в пользовательскую директорию
Код:
bool isDebug = false;

/// Разбор параметров запуска
void parseArg(int argc, char *argv[])
{
    for (int i=1; i<argc; i++)
        if (strcmp(argv[i], "-debug")==0)
            isDebug = true; /// Включение расширенной отладки
}

/// Перенаправление отладочного вывода
void myMessageOutput(QtMsgType type, const char *msg)
{
    QString filename("debug.log");
    if (qApp)
        filename = QDesktopServices::storageLocation(QDesktopServices::DataLocation) +
                   "/" +
                   qApp->applicationName() +
                   qApp->applicationVersion() +
                   "." + QString::number(qApp->applicationPid()) + ".log";
       FILE *file;
       file = fopen(filename.toStdString().c_str(), "a");
       if (file)
       {
           switch (type) {
           case QtDebugMsg:
               fprintf(file, "Debug: %s\n", msg);
               break;
           case QtWarningMsg:
               fprintf(file, "Warning: %s\n", msg);
               break;
           case QtCriticalMsg:
               fprintf(file, "Critical: %s\n", msg);
               break;
           case QtFatalMsg:
               fprintf(file, "Fatal: %s\n", msg);
               abort();
           }
           fclose(file);
        }

    #ifndef QT_NO_DEBUG
       isDebug = true;
    #endif

       if (isDebug || !file)
       {
        QString wstr(QString(msg)+"\n");
        OutputDebugString((WCHAR*)wstr.constData());

        if(type == QtFatalMsg)
        {
                    asm("int $0x3");
                    abort();
        }
       }
}
Ну а конфиг подтягивать наверное так
Код:
    QString settingsFile("settings.ini");
    if (qApp)
        filename = QDesktopServices::storageLocation(QDesktopServices::DataLocation) +
                   "/" +
                   qApp->applicationName()  +
                   ".ini";

Какие могут быть (а значит рано или поздно точно будут) косяки в такими вариантами?


Название: Re: Кроссплатформенное логирование
Отправлено: asvil от Март 30, 2012, 13:08
Внезапно кроссплатформенность --- миф.

Напомню, что под виндовсом логи принято сбрасывать в какой-то там event log.


Название: Re: Кроссплатформенное логирование
Отправлено: sidsukana от Март 30, 2012, 13:15
Log4Qt не пробовал юзать?


Название: Re: Кроссплатформенное логирование
Отправлено: QuAzI от Март 30, 2012, 13:36
Внезапно кроссплатформенность --- миф.
Если вы о том, что придётся перелинковывать под каждую платформу, то я в курсе. Или поясните своё ИМХО
Цитировать
Напомню, что под виндовсом логи принято сбрасывать в какой-то там event log.
Ткните в этот event log. Если это то, куда гадят все сервисы, то там и так вечный хаос и туда попадают далеко не все логи. В юнихах тоже есть syslogd, но у него хоть можно логи разделить адекватно.

sidsukana, если честно не видел эту штуку ни разу. Попробую. Спасибо.


Название: Re: Кроссплатформенное логирование
Отправлено: asvil от Март 30, 2012, 13:43
Ну это значит кроссплатформенных способов не бывает. Бывают простыни из if defined OS1 else if OS2 .... end if

Вечного хаоса там нет, event log имеет структуру, уровни сообщений, позволяет сохранять бинарные данные.
И что значит попадают не все логи?


Название: Re: Кроссплатформенное логирование
Отправлено: QuAzI от Март 30, 2012, 13:53
Я понимаю, что в принципе почти всё - это какие-то простыни, костыли и наборы стандартных функций, но одно дело колхозить что-то кривоватое самому и другое дело юзать Qt-шный метод, который писали не такие чайники, как я и уже довольно серьёзно обкатали в эксплуатации.

Ты имеешь ввиду тот лог, который можно почитать через Панель управления - Администрирование - Журнал событий? Точно помню, что у меня падали туда события о том, что службы стартанули, остановились или что-то грохнулось с ошибкой, но например тот же брандмауэр пишет отдельный лог, служба удалённого доступа (модемный дозвон) в XP кидает логи прямо в папку винды, вида modem<марка>.log, ну и так далее. Т.е. не суют там все логи в одну кучу. Да и выдёргивать их оттуда чтобы распарить тем же grep или по почте отправить - тоже удовольствие ниже среднего. Файловые логи как-то привычнее.


Название: Re: Кроссплатформенное логирование
Отправлено: sidsukana от Март 30, 2012, 13:55

sidsukana, если честно не видел эту штуку ни разу. Попробую. Спасибо.


Выше постом автор этой штуки :)


Название: Re: Кроссплатформенное логирование
Отправлено: asvil от Март 30, 2012, 14:12
Ну файловые, так файловые. Значит в самой винде разброд и шатаниие.

nix программы портированные на win, чаще всего у себя в %PROGRAMFILES%/ устраивают небольшую nix структуру типа
bin/
etc/
share/
....

Но это для статических данных. Для динамических же данных используется домашний каталог пользователя, как уже было сказано. Для этого достаточно googleit QDesktopServices::HomeLocation


Название: Re: Кроссплатформенное логирование
Отправлено: asvil от Март 30, 2012, 14:17
log4qt я форкнул и доделывал под себя лишь несколько классов.


Название: Re: Кроссплатформенное логирование
Отправлено: QuAzI от Март 30, 2012, 14:41
Цитировать
nix программы портированные на win, чаще всего у себя в %PROGRAMFILES%/ устраивают небольшую nix структуру типа
bin/
etc/
share/
....
Видел. Это наследие cygwin =) У того же VLC например всё в порядке с именованием и на Win и на FreeBSD.

Цитировать
Но это для статических данных. Для динамических же данных используется домашний каталог пользователя, как уже было сказано. Для этого достаточно googleit QDesktopServices::HomeLocation
Зачем googleit, я же и так для этого QDesktopServices использую. Только в корень хомяка не хорошо захламлять, поэтому ::DataLocation всё же лучше.


Название: Re: Кроссплатформенное логирование
Отправлено: QuAzI от Март 30, 2012, 18:15
Почитал про log4qt (http://www.prog.org.ru/topic_13224_0.html). Красиво конечно, но это скорее для более серьёзных проектов, для моей мелкотни пока такое рано =)