Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Bepec от Март 28, 2014, 10:15



Название: Просмотрщик логов.
Отправлено: Bepec от Март 28, 2014, 10:15
День добрый заглянувшим.

Имеется: лог от 1 до N тысяч строк вида
Код:
"время     источник:     данные"

Хотелка: подключать, отключать показ источников.
Т.е. к примеру хочу посмотреть все действия пользователя, тык галку User и показывает все записи с источником User.

Проблема: Собственно в размере и подходе. Сам я вижу 2 подхода:
1. Просто перебором строк по условию выдавать только нужные.
Код:
if(line.contains("User"))
    viewRow();


-  Но время обработки большое, тем более что сообщения могут быть разбросаны очень сильно. Так же обновление лога ведёт к пересчёту строк.

2. Забивать данные в какой-нибудь контейнер с ключом в виде источника.
Код:
map["User"] = "время     источник:     данные";

+ Быстрый вывод.
- контейнер много места занимать будет.

Общий минус обоих подходов - с большими файлами они не справятся, ибо в 1 случае будет тормоз и вылет из-за переполнения, во 2 случае будет переполнение.

Вопрос: как сделать лучше. Предлагайте свои варианты. Если есть литература, то приводите литературу. Буду рад любой информации.


Название: Re: Просмотрщик логов.
Отправлено: _OLEGator_ от Март 28, 2014, 10:35
Использовать SQLite.


Название: Re: Просмотрщик логов.
Отправлено: Swa от Март 28, 2014, 10:57
Переполнение чего?

Можно немного оптимизировать:

Создаем справочник источников:
Код:
QMap<QString, int> sourceMap;
Для каждого источника создаем идентификатор ID типа int и заносим в этот справочник (н-р "Source1" = 1, "Source2" = 2). Это для того, чтобы строку, которая может быть большой, заменить на 4-байтный идентификатор.

Далее создаем основной контейнер:
Код:
QMultiHash<int, int> filter;
, где ключ - ID источника, а значение - номер строки в лог-файле.

Также после первоначального парсинга лог файла нужно запомнить последнюю строку, и после изменения этого файла читать начиная с этой строки, а не с начала.


Название: Re: Просмотрщик логов.
Отправлено: Bepec от Март 28, 2014, 11:01
Переполнение памяти. > 2 Гб. Ибо каждая строка это примерно 40-90 байт. Строк может быть очень много.


Название: Re: Просмотрщик логов.
Отправлено: OKTA от Март 28, 2014, 11:02
Использовать SQLite.

Поддерживаю  :)


Название: Re: Просмотрщик логов.
Отправлено: Bepec от Март 28, 2014, 12:09
Не вариант. Нужно чтобы можно было посмотреть и в файле пользователю.
Хотя с sqlite тоже проблема - из-за того что нет готовых SQl модель-вью для большой нагрузки.


Название: Re: Просмотрщик логов.
Отправлено: OKTA от Март 28, 2014, 12:15
Да там не придется мучиться с нагрузкой - загружаешь/выгружаешь кусками и все чики пуки  ;D А с файлом да, косячок  :-\


Название: Re: Просмотрщик логов.
Отправлено: Old от Март 28, 2014, 14:19
Далее создаем основной контейнер:
Код:
QMultiHash<int, int> filter;
, где ключ - ID источника, а значение - номер строки в лог-файле.
Лучше хранить не номер строки, а абсолютное смещение от начала файла. Тогда можно будет seek & read.


Название: Re: Просмотрщик логов.
Отправлено: OKTA от Март 28, 2014, 14:32
При использовании SQlite можно использовать функцию выгрузки данных из БД в файл. ИМХО, если файл очень большой, то вряд ли кто-то будет просматривать его целиком - человек будет смотреть самые последние строки. А как альтернатива. хотя и не комильфо - разделить файлы логов по источникам сразу, чтобы для каждого отдельный файлик велся:)


Название: Re: Просмотрщик логов.
Отправлено: Swa от Март 28, 2014, 14:35
Далее создаем основной контейнер:
Код:
QMultiHash<int, int> filter;
, где ключ - ID источника, а значение - номер строки в лог-файле.
Лучше хранить не номер строки, а абсолютное смещение от начала файла. Тогда можно будет seek & read.

Да, так будет правильнее


Название: Re: Просмотрщик логов.
Отправлено: Igors от Март 28, 2014, 14:57
В памяти массив примерно таких структур
Код
C++ (Qt)
struct Key {
qint64 mOffset;  // смещение строки от начала файла
int key1ID;        // ID "источника"
int key2ID;        // ID "данные" (если нужно)
...                    // др возможные ключи
};
Если нужно пополнять, то вместо массива дека. Ну и просто сортируем (первый последний ключ offset) и считываем нужные строки. Альтернатива: 64-bit и памяти побольше