Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Работа с логами  (Прочитано 33653 раз)
0 Пользователей и 1 Гость смотрят эту тему.
sav-ledi
Участник

ru
Offline Offline

« : 19-05-2011 16:46 » 

I need help!

Задача: в директории лежит несколько сотен файлов(логи с атс), в таком вот виде:
Имя                  Размер             Изменён
2011032600.log       1995 КБ            26.03.2011 1:57
2011032601.log       2054 КБ            26.04.2011 7:56
2011032602.log       1271 КБ            20.05.2011 15:17
и т.д
Внутри файлов информация о звонках, в таком вот виде:

110326 010803 000000 010843 --- 4500 ---- 021 031524 059 4593 --- 050110 0000 564593------------ 9615574500
110326 010955 000000 011008 --- 4500 ---- 020 032322 059 4593 --- 050110 0000 564593------------ 9615574500
110326 010256 010307 011152 104 ---- 4678 --- 050615 007 ---- 020 032321 0027 532416------------ ----------
110326 004525 004536 011241 104 ---- 4861 --- 051806 007 ---- 020 032313 0027 521411------------ ----------
110326 011350 000000 011420 --- 4500 ---- 021 031525 059 4593 --- 050110 0000 564593------------ 9615574500
110326 011435 000000 011436 104 ---- 4335 --- 040908 005 ---- --- ------ 0000 ------------------ ----------
110326 011437 000000 011438 104 ---- 4336 --- 040909 005 ---- --- ------ 0000 ------------------ ----------
110326 003414 003416 011552 --- 5480 ---- 020 032308 059 4480 --- 042413 0000 564480------------ 3499525480
110326 011934 000000 011937 104 ---- 4678 --- 050615 007 ---- --- ------ 0000 ------------------ ----------

Это информация о звонках. Из всей этой информации мне нужно обрабатывать всего 5 столбцов, таких как: выбирать только звонки сделанные в апреле, номер с которого звонили, на какой звонили, и разницу между ночалом разговора и концом разговора, то есть суммарное время общения.
При этом, всю эту выборку мне надо осуществить всего для 10ти телефонных номеров.
То есть, из тысяч записей в каждом из сотен txt файлов данной директории, мне необходимо выполнить поиск по дате и номеру, в случае если все атрибуты совпадают(дата, номер с которого звонили, на какой звонили) то проссуммровать время общения за весь апрель.
А в итоге обработанную красивую информацию записать в новый txt.
У меня кипят мозги.

Вопрос: Подскажите пожалуйста, как это правильно реализовать, да так чтоб сервак не повис на веки вечные!!!
Пишу на C# в Visual Studio.
« Последнее редактирование: 19-05-2011 17:46 от Вад » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 19-05-2011 16:52 » 

если задание не разовое и не сиюсекундное, то я бы сначала загнал всё в БД. Сделается это быстро, а потом пригодится. Работать будет удобно.

Если задание разовое, то ничего, кроме как открывать по одному файлу, парсить и накапливать в массиве нужные записи. Нагрузки на машину не предвидится большой, кстати.
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 19-05-2011 16:58 » 

Это второй заход на вот эту - https://forum.shelek.ru/index.php/topic,27130 - тему?
Почему в C++ в этот раз?

Записан
sav-ledi
Участник

ru
Offline Offline

« Ответ #3 : 19-05-2011 17:03 » 

Да нет, там просто был совсем приметивный вопрос. Там сама запарилась, забыла как txt разбирать и про волшебный substring. А тут задачка то вроде посерьёзней. Стыдно как-то на форум в помощь начинающим. А про С++, долго выбирала нужную тему, пошла сюда, потому что с него на С# перевести свою прогу смогу.

К вопросу:
А загонять это всё в бд, тоже открывая ручками каждый файл?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 19-05-2011 17:05 » 

ну можно не ручками, а написать программку для этого Улыбаюсь
Записан

sav-ledi
Участник

ru
Offline Offline

« Ответ #5 : 19-05-2011 17:07 » 

а по подробней? я просто с этим не сталкивалась: из txt в субд
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 19-05-2011 17:10 » 

а ты какую СУБД выбрала ? )

А подробнее не могу, занят немного. И в любом случае с шарпом не дружу
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 19-05-2011 17:12 » 

Зачем же писать на C++, а потом транслировать на C#, если можно сразу на C#?

Я так понимаю, главный пугающий фактор - объём информации, по которой надо пробегать при каждом запросе.
Действительно, избежать многократного полного прохода по всем данным почти во всех случаях можно только индексированием (в частности, можно возложить эту задачу на СУБД).

Но если задача, всё-таки, проще, т.е. не требует оптимизировать индексацию (дали сразу 10 номеров и попросили отчёт только по ним и только за апрель), то, очевидно, что число файлов резко сокращается фильтром по дате (если апрель - там всего 30 файлов будет, если я всё правильно понимаю), а остальное - дело техники.
Записан
sav-ledi
Участник

ru
Offline Offline

« Ответ #8 : 19-05-2011 17:14 » 

ну у меня SQL Server 2005 стоит, ну и несравненный Access ещё есть, но это думаю врядли.

Добавлено через 5 минут и 42 секунды:
Цитата
Но если задача, всё-таки, проще, т.е. не требует оптимизировать индексацию (дали сразу 10 номеров и попросили отчёт только по ним и только за апрель), то, очевидно, что число файлов резко сокращается фильтром по дате (если апрель - там всего 30 файлов будет, если я всё правильно понимаю), а остальное - дело техники.
Нет. Дата у файла не показатель Не знаю чего у них там за глюк с АТСками, однако в файлах, созданных с марте, могут быть разговоры за апрель. Обрабатывать надо все файлы.

Добавлено через 2 минуты и 50 секунд:
А правда, как эти данные быстро загнать в СУБД, там я уже запросами всё сто угодно с ними сделаю.
« Последнее редактирование: 19-05-2011 17:20 от sav-ledi » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 19-05-2011 17:20 » 

sav-ledi, первые шаги такие:
1)напиши процедуру открытия файла и реализуй поочерёдное определение записей.
2)Каждую отделённую запись передавай в следующую процедуру, которая распарсит эту запись
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 19-05-2011 17:21 » 

Даты или имена? я думал, имена файлов - это и есть дата: 2011032601 = 2011/03/26, часть 1
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #11 : 19-05-2011 17:24 » 

возьмите скрипты и не парьтесь Улыбаюсь
bash awk grep спасут отца русской демократии

пара тройка гигов логов не так уж и много, ну поработают скрипты несколько минут, зачем c++ код городить ради этого, ну если только не стоит задачи написать на C++/C# или еще какой-нибудь такой фиговине

иж базу данных поднимать я тоже не стал

это всё ИМХО конечно, из описани задачи не как не следует, что её будут часто повторять, ничего не сказано про скорость, в общем выглядит как типичная скриптовая задача
я бы её может быть даже на python написал, что-то он мне последнее время всё роднее и DB-API хорошее

Записан

Странно всё это....
sav-ledi
Участник

ru
Offline Offline

« Ответ #12 : 19-05-2011 17:27 » 

я обрезала названия файлов, вот они полные:
COM18-Harris2011032704.log


Добавлено через 3 минуты и 16 секунд:
Цитата
bash awk grep спасут отца русской демократии

честно говоря я не знаю что это такое, а изучать некогда, решение данной задачи мне надо предоставить завтра к обеду.
« Последнее редактирование: 19-05-2011 17:30 от sav-ledi » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 19-05-2011 17:31 » 

пошла сюда, потому что с него на С# перевести свою прогу смогу.

Ерунда. Зачем это нужно делать в С++, чтобы потом героически переводить в С#?

И что собственно сложного? Шаги предельно просты и понятны.

1. Необходимо собрать данные из всех файлов. В БД или нет - это вопрос оптимизации, ресурсов и тд.
2. Произвести поиск в собранных данных любым доступным способом.

Для более детальных рекомендаций ессно не хватает информации.
Какой ожидаемый выход данных? 2-3 записи? 200-300? 200 000-300 000?
Как часто нужно производить подобную операцию? Какие ограничения есть на доступ к файлам? Считается, что один лог-файл создаётся только один раз, или же он может изменяться? Как быть с логами, которые создаются в момент работы программы поиска?

Если:

мне необходимо выполнить поиск по дате

, то ответ на

А загонять это всё в бд, тоже открывая ручками каждый файл?

очевиден. Совершенно необязательно открывать сотни файлов. Можно открыть только те, которые созданы в нужный момент времени. При условии, конечно, что лог-файл содержит информацию о дне, когда он был создан, или же его имя говорит об этом (как в примере: 20110326 -> 26 марта 2001 г.). Ессно, что делать это ручками крайне неспортивно.

зы И C# они тоже разные бывают. Ага 1.1 это совсем не то, что, к примеру, 3.5.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #14 : 19-05-2011 17:34 » 

я обрезала названия файлов, вот они полные:
COM18-Harris2011032704.log

Так в этом имени 20110327 - это дата или нет?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 19-05-2011 17:36 » 

решение данной задачи мне надо предоставить завтра к обеду.

Ну а у самой какие решения в голове есть? Самая короткая дорога та, которую хорошо знаешь. Это непреложная истина.
C# великолепно справится с этой задачей. Парсер у тебя есть, который строчку на элементы разбивает? Остальное - дело 27 минут, включая перекур.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 19-05-2011 17:37 » 

В целом, поддерживаю Джона: скрипт на Питоне или Перле написать можно за пару часов, практически не зная языка и пользуясь только базовыми конструкциями и гуглом Улыбаюсь

Если язык реализации не регламентирован - я бы предпочёл такой, для которого тексты парсить - родное.
Записан
sav-ledi
Участник

ru
Offline Offline

« Ответ #17 : 19-05-2011 17:38 » 

Джон

что вы прикопались к С++, я не на том форуме изночально написала вопрос. Это раз.

поиск по дате надо осуществлять внутри файла. Поскольку, повторюсь: в 1 файле могут быть собраны звонки за 3 месяца.

Файлы лежат статично и не меняются во время работы программы.

Выход данныз, это 200-300 записей.

Данную операцию нужно будет делать часто
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #18 : 19-05-2011 17:40 » 

в каких полях входящий и исходящий номера? с остальными понятно.
Записан

Странно всё это....
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #19 : 19-05-2011 17:45 » 

Антон (LogRus), Был бы разговор под *nix системы, я думаю сразу бы скрипты бы и предложили. Намного быстрее и практичнее. Но в Виндовсе еше надо установить perl, Python, awk, grep. И не на всех машинах это будет.

Добавлено через 2 минуты и 1 секунду:
Джон, А зачем парсер? Регулярные выражения вроде как есть в Шарпе.
« Последнее редактирование: 19-05-2011 17:47 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
sav-ledi
Участник

ru
Offline Offline

« Ответ #20 : 19-05-2011 17:50 » 

Цитата
в каких полях входящий и исходящий номера? с остальными понятно.

в 2ух последних номера.
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 19-05-2011 17:51 » 

Антон (LogRus), Был бы разговор под *nix системы, я думаю сразу бы скрипты бы и предложили. Намного быстрее и практичнее. Но в Виндовсе еше надо установить perl, Python, awk, grep. И не на всех машинах это будет.
Ну, мы пока так и не выяснили требований к решению до конца. Пока только упоминался какой-то сервер, который нужно не слишком нагружать (из чего можно рискнуть сделать вывод, что исполняться всё это будет на одной целевой машине с неизвестной средой, но с наличием .NET/Mono)
Записан
sav-ledi
Участник

ru
Offline Offline

« Ответ #22 : 19-05-2011 17:52 » 

кто-нибудь может мне сказать, как в шарпе последовательно, автоматически открывать эти файлы, обработать инфу изнутри я смогу
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #23 : 19-05-2011 17:55 » 

sav-ledi, Ну вроде как есть класс с названием dir (могу и ошибаться в точности названия). У него есть методы, которые просматривают каталог и дают список содержимого. Тебе только остается отделить нужные файлы от всех остальных.

Добавлено через 2 минуты и 12 секунд:
Антон (LogRus), Был бы разговор под *nix системы, я думаю сразу бы скрипты бы и предложили. Намного быстрее и практичнее. Но в Виндовсе еше надо установить perl, Python, awk, grep. И не на всех машинах это будет.
Ну, мы пока так и не выяснили требований к решению до конца. Пока только упоминался какой-то сервер, который нужно не слишком нагружать (из чего можно рискнуть сделать вывод, что исполняться всё это будет на одной целевой машине с неизвестной средой, но с наличием .NET/Mono)
Когда я смотрел в последний раз на Mono, это было ужасно. Простейшие програмки просто не компилировались. За года 4 я думаю его отрихтовали конечно.
« Последнее редактирование: 19-05-2011 17:58 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
sav-ledi
Участник

ru
Offline Offline

« Ответ #24 : 19-05-2011 17:58 » 

Цитата
Ну, мы пока так и не выяснили требований к решению до конца. Пока только упоминался какой-то сервер, который нужно не слишком нагружать (из чего можно рискнуть сделать вывод, что исполняться всё это будет на одной целевой машине с неизвестной средой, но с наличием .NET/Mono)
Представляете сколько логоф приходит с АТС в фирме обслуживающей порядка 10 000 номеров. В дальнейшем это всё надо поставить на поток. Написать нармальную прогу, завязать с СУБД. Но сейча мне надо выгрузку сделать по 10 ти номерам. И на данный момент никому совершенно не важно как я это реализую.

Я просто сишный практически студент, до данной задачи, занимающийся исключительно webом. поэтому мне тяжеловато перестроиться
Записан
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 19-05-2011 17:59 » 

sav-ledi, Ну вроде как есть класс с названием dir (могу и ошибаться в точности названия). У него есть методы, которые просматривают каталог и дают список содержимого. Тебе только остается отделить нужные файлы от всех остальных.
Directory - http://msdn.microsoft.com/en-us/library/system.io.directory.aspx
Там есть метод EnumerateFiles. В одной из перегрузок которого даже поисковые паттерны задавать можно
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #26 : 19-05-2011 18:02 » 

Цитата
кто-нибудь может мне сказать, как в шарпе последовательно, автоматически открывать эти файлы, обработать инфу изнутри я смогу


Код: (C#)
       string[] files = Directory.GetFiles(путь к папке, "*.log", SearchOption.TopDirectoryOnly);
       foreach (string file in files)
       {
            using (StreamReader sr = new StreamReader(file))
            {
                while ((line = sr.ReadLine()) != null)
                {
                    делаешь всё что хочешь с line
                }
            }
        }
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
sav-ledi
Участник

ru
Offline Offline

« Ответ #27 : 19-05-2011 18:06 » 

Джон
Щас попробую. Благодарю за советы...
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #28 : 19-05-2011 18:08 » 

Только не забудь взять тело первого цикла в try-catch, а то вдруг какой-нить файл не читается.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
sav-ledi
Участник

ru
Offline Offline

« Ответ #29 : 19-05-2011 18:11 » 

Цитата
Только не забудь взять тело первого цикла в try-catch, а то вдруг какой-нить файл не читается.

Ну уш это-то я знаю. Но всё равно спасибо.
Записан
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #30 : 19-05-2011 18:18 » 

ради удовольствия и прокачки пинонячьего навыка Улыбаюсь
Код: (Python)
import sys

def check_phone(date, nums, num_a, num_b):
    return date[2:4] == '04' and (num_a in nums or num_b in nums)

def dtime_to_str(tstr):
    return "%s:%s:%s" % (tstr[:2], tstr[2:4], tstr[4:])

def time_delta(from_date, to_date):
    f_h = int(from_date[:2])
    f_s = int(from_date[2:4])*60 + int(from_date[4:])
    t_h = int(to_date[:2])
    t_s = int(to_date[2:4])*60 + int(to_date[4:])
    if (t_h < f_h):
        t_h += 24 - f_h
    f_tm = f_h*3600 + f_s
    t_tm = t_h*3600 + t_s
    return t_tm - f_tm

for line in sys.stdin:
    line = line.strip()
    fields = line.split(' ')
    dfield = fields[0]
    num_a = fields[-2]
    num_b = fields[-1]
    if not check_phone(dfield, ['9615574500', '532416'] ,num_a.strip('-'),num_b.strip('-')):
        continue
    start_time = fields[1]
    date_day = "20%s-%s" % (dtime_to_str(dfield), dtime_to_str(start_time))
    con_time = fields[2]
    term_time = fields[3]
    term_time_str = dtime_to_str(term_time)
    dur = 0
    con_time_str = '--------'
    if (con_time != '000000'):
        dur = time_delta(con_time, term_time)
        con_time_str = dtime_to_str(con_time)
    print "%s %s %s %05s %s %s" % (date_day, con_time_str, term_time, dur, num_a, num_b)

Добавлено через 11 минут и 30 секунд:
запускается строчкой
find . -name *201104*.log | while read f; do cat $f; done|python tel.py
2011:04:26-01:09:55 -------- 011008     0 564593------------ 9615574500
2011:04:26-01:02:56 01:03:07 011152   525 532416------------ ----------


Добавлено через 3 минуты и 20 секунд:
думаю если задача частая, то имеет смысл создать инфраструктуру которая будет инкрементально наполнять БД новыми звонками (думаю лучше хранить все поля), а потом по ней делать запрос

PS: я полагаю, что в третьем поле лежит время установки соединения (момент когда сняли трубку), если там пусто, то трубку не снимали
« Последнее редактирование: 19-05-2011 18:43 от Антон (LogRus) » Записан

Странно всё это....
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #31 : 19-05-2011 19:01 » 

Если нужно разово достать, а не периодически доставать данные за разные периоды, то лучше без базы обойтись, т.к. объемы большие.

Можно попробовать без C++ - скриптами. Например:

Код: (DOS) test.bat
@echo off

for /f "usebackq tokens=*" %%a in (`dir *.log /B /ON`) do for /f "usebackq tokens=*" %%b in (%%a) do call :filter %%b
goto :eof

:filter
for /f "usebackq tokens=1,2" %%a in ('%*') do if %%a GTR 110300 if %%a LSS 110400 if %%b GTR 003000 if %%b LSS 010000 echo %*
goto :eof

Выборка файлов, фильтрация строк по дате и по диапазону времени 00:30:00..00:59:59.
« Последнее редактирование: 19-05-2011 19:04 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines