Имя: Пароль:
1C
 
Мой гений дарит анализатор лога и просит совета
Ø
0 Гений 1С
 
17.12.04
18:11
Написал функцию, которая извлекает лог в таблицу значений, используя виндовую команду findstr.
Лог длиной 191 мегабайт копируется 1 минуту и сканируется также одну минуту.
Просьба совета - как отрезать от лога последний мегабайт для оперативного изучения (лог-то большой). Может команда доса есть или че такое...
//Возвращает таблицу значений
Функция Дата_Из_ГГГГММДД(Стр)
  Возврат Дата(Сред(Стр,1,4),Сред(Стр,5,2),Сред(Стр,7,2));
КонецФункции
Функция Дата_В_ГГГГММДД(Дат)
  Возврат
    Формат(ДатаГод(Дат),"Ч(0)4")+
    Формат(ДатаМесяц(Дат),"Ч(0)2")+
    Формат(ДатаЧисло(Дат),"Ч(0)2");
КонецФункции
Функция ПоискВЛоге(КаталогБазы="", НачДата=0,КонДата=0)
  Перем Т;
  Т=СоздатьОбъект("ТаблицаЗначений");
  
  Если КаталогБазы="" Тогда КаталогБазы=КаталогИБ(); КонецЕсли;
  КаталогБазы=СокрЛП(КаталогБазы); КаталогБазы=КаталогБазы+?(Прав(КаталогБазы,1)="\","","\");
  ИмяФайлаЛога=КаталогБазы+"syslog\1cv7.mlg";
  ИмяФайлаВремЛога=КаталогБазы+"syslog\1cv7prev.mlg";
  ИмяФайлаФильтра=КаталогБазы+"syslog\1cv7prevf.mlg";
  //Если ЗагрузитьВнешнююКомпоненту("v7plus.dll")=0 Тогда
  // Сообщить("Не удалось обнаружить компоненту v7plus.dll!");
  // Возврат 0;
  //КонецЕсли;
  
  Состояние(Шаблон("Копирую лог [ИмяФайлаЛога] в [ИмяФайлаВремЛога]"));
  //ИмяФайлаВремЛога=ИмяФайлаЛога;
  ФС.КопироватьФайл(ИмяФайлаЛога,ИмяФайлаВремЛога,0);
  //Файл=СоздатьОбъект("AddIn.V7TextFile");
  //Файл.ОткрытьФайл(ИмяФайлаВремЛога, 0);
  //Файл.РазмерБуфера(100000);
  ШабПоиска="";
  Для ИндД=НачДата По КонДата Цикл
    ШабПоиска=ШабПоиска+?(ШабПоиска="",""," ")+Дата_В_ГГГГММДД(ИндД);
  КонецЦикла;
  
  ФС.УдалитьФайл(ИмяФайлаФильтра);
  СтрокаЗапуска="findstr /B """+ШабПоиска+""" """ + ИмяФайлаВремЛога+ """" +">>"""+ИмяФайлаФильтра+"""";
  КомандаСистемы(СтрокаЗапуска);
  //Сообщить(СтрокаЗапуска);
  Если ФС.СуществуетФайл(ИмяФайлаФильтра)=0 Тогда
    Сообщить(Шаблон("Не удалось отфильтровать лог [ИмяФайлаЛога] в файл [ИмяФайлаФильтра]!"));
    Возврат 0;
  КонецЕсли;
  //Состояние(Шаблон("Открываю лог [ИмяФайлаФильтра] для чтения"));
  Форма.Обновить(1);
  Файл=СоздатьОбъект("Текст");
  Файл.Открыть(ИмяФайлаФильтра);
  
  Стр="";
  Т.НоваяКолонка("Дата","Дата");
  Т.НоваяКолонка("Время","Строка");
  Т.НоваяКолонка("Пользователь","Строка"); //Строка с именем пользователя
  Т.НоваяКолонка("РежимЗапуска","Строка",1); //E,C,M - монитор, предприятие, конфигугатор
  Т.НоваяКолонка("ТипСобытия","Строка");
  Т.НоваяКолонка("Событие","Строка");
  Т.НоваяКолонка("Категория","Число",1);
  Т.НоваяКолонка("Комментарий","Строка");
  Т.НоваяКолонка("Объект");
  Т.НоваяКолонка("ПредставлениеОбъекта","Строка");
  
  ПредДата=0;
  
  //Файл.ВыбратьСтроки();
  //Пока Файл.ПрочитатьСтроку(Стр)=1 Цикл
  //Файл.ВыбратьСтроки();
  
  КоличествоСтрокФайла=Файл.КоличествоСтрок();
  //Сообщить(Шаблон("Строк в файле =[КоличествоСтрокФайла]"));
  ИндСтр=1;
  Пока ИндСтр<КоличествоСтрокФайла Цикл
    Стр=Файл.ПолучитьСтроку(ИндСтр); ИндСтр=ИндСтр+1;
    //Сообщить(Стр);
    ТекДата=Дата_Из_ГГГГММДД(Строка_ДоРазделителя(Стр, ";"));
    
    Если ТекДата<>ПредДата Тогда
      Состояние(Строка(ТекДата));
      ПредДата=ТекДата;
    КонецЕсли;
    Если НачДата<>0 Тогда Если ТекДата<НачДата Тогда Продолжить; КонецЕсли; КонецЕсли;
    Если КонДата<>0 Тогда Если ТекДата>КонДата Тогда Прервать; КонецЕсли; КонецЕсли;
    
    ТекВремя=Строка_ДоРазделителя(Стр, ";");
    ТекПользователь=Строка_ДоРазделителя(Стр, ";");
    ТекРежимЗапуска=Строка_ДоРазделителя(Стр, ";");
    ТекТипСобытия=Строка_ДоРазделителя(Стр, ";");
    ТекСобытие=Строка_ДоРазделителя(Стр, ";");
    ТекКатегория=Число(Строка_ДоРазделителя(Стр, ";"));
    ТекКомментарий=Строка_ДоРазделителя(Стр, ";");
    ТекОбъект=ЗначениеИзСтрокиВнутр(Строка_ДоРазделителя(Стр, ";"));
    ТекПредставлениеОбъекта=Строка_ДоРазделителя(Стр, ";");
    
    Т.НоваяСтрока();
    Т.Дата=ТекДата;
    Т.Время=ТекВремя;
    Т.Пользователь=ТекПользователь;
    Т.РежимЗапуска=ТекРежимЗапуска;
    Т.ТипСобытия=ТекТипСобытия; //Остаток строки
    Т.Событие=ТекСобытие;
    Т.Категория=ТекКатегория;
    Т.Комментарий=ТекКомментарий;
    Т.Объект=ТекОбъект;
    Т.ПредставлениеОбъекта=ТекПредставлениеОбъекта;
  КонецЦикла;
  //Файл.ЗакрытьФайл();
  глВыполнитьПроцедуру("РедакторТЗ",Контекст,Т);
КонецФункции
1 Тупой 1Assник
 
17.12.04
18:13
Как твоя мобила поживает?
2 дохтур
 
17.12.04
18:18
а кто такой вуглускр?
3 дохтур
 
17.12.04
18:23
гений блин, примитивную вещь сделать ума не хватает, а туда-же бороздить просторы...
возьми резалку файлов на вебфайле номер 127266, пароль на скачку, надеюсь гениальну угадаешь. и режь себе свой лог хоть в мелкую полосочку.
4 Uho
 
17.12.04
18:27
(0) Я делал так:
открывал в объекте "Текст", перебирал строчки с конца, загружал в ТЗ необходимые мне данные, далее запоминал дату и время записи, и при последующем обращении к логу выбирал записи только после запомненной позиции. Первое обращение долгое, зато последующие - очень быстро.
  
Также можно определенное кол-во строк с конца прочитать, или по времени. Или нужен ровно 1 мегабайт?
5 fez
 
17.12.04
18:43
(0) Поставь себе cygwin, там есть tail
6 Гений 1С
 
17.12.04
19:08
(3) Подробнее, плиз
(4) Объект текст загружает весь файл в память. Пробовали 190 метров в память вогнать?
(5) А ченить постандартнее?
Хотя на самом деле минута на поиск - достаточно нормальная скорость, учитывая что ищу с начала строки (максимально быстро).
Так что если б еще этот findstr работал с самим логом, интересно почему файл копируется, а findstr не может его прочитать???
т.е. copy работает а findstr нет???
7 MMF
 
17.12.04
19:11
быстрее, чем с проекцией в память, ИМХО, нет способа.
8 MMF
 
17.12.04
19:13
Хороший идентификатор Строка_ДоРазделителя. Сразу видно - гений писал.
9 fez
 
17.12.04
19:24
(6) Стандартный такой юниксовый tail :)
А вообще наверное можно через
fso = new ActiveXObject("Scripting.FileSystemObject")
.
И потом
f = fso.OpenTextFile("c:\\testfile.txt", ForReading);
f.Skip(195000000)
lastMegabyte = f.Read(1000000)
10 Guk
 
17.12.04
19:35
(0) ;)...
11 fez
 
17.12.04
19:46
(0)
"Функция Дата_В_ГГГГММДД(Дат)
  Возврат
    Формат(ДатаГод(Дат),"Ч(0)4")+
    Формат(ДатаМесяц(Дат),"Ч(0)2")+
    Формат(ДатаЧисло(Дат),"Ч(0)2");
КонецФункции"
.
Дарю. Формат(Дат, "ДГГГГММДД")
12 saasa
 
17.12.04
20:18
(11) Зачем ты так, он же Гений ;)
Обидится ещё.
13 fez
 
17.12.04
21:16
(12) Да ну брось ты. У нашего Гения толерантность очень высокая. Я бы даже сказал - феноменальная.
14 дохтур
 
17.12.04
21:34
(6) просил подробнее? ок. для Гениев объясняю. это ццц.webfile.ru/127266
пароль на скачку 127266
20 килобайт - резалка файлов. призапуске выдается легкий хинт
Usage: CUTTER fromFile toFile fromOffset toOffset
E.G. CUTTER x1.bin x2.bin 0 255 [0]..[255]
        CUTTER x1.bin x2.bin 255 0[255]..[EOF]
        CUTTER x1.bin x2.bin 100h 0[0x100]..[EOF]
что означает:
fromFile - файл который режем
toFile - то, куда запишется результат
fromOffset toOffset - начало и конец выборки соответственно.
если они в виде: 0 255 - то с байта 0 по байт 255,
если в виде: 255 0 - то с байта 255 по конец файла,
если стоит буковка "h" то значения берутся в хексе.