/// <summary> /// Принудительная очистка журнала /// </summary> /// <param name="fromDate">Фильтр по дате-времени, начальное значение</param> /// <param name="toDate">Фильтр по дате-времени, конечное значение</param> public void TruncLog(DateTime fromDate, DateTime toDate) { var iterator = new Iterators.LogsIterator(GetStorageName); foreach (var storageName in iterator.LogsRundown(fromDate, toDate)) { try { File.Delete(storageName); } catch (IOException) { } } }
/// <summary> /// Перебирает события в логах /// </summary> /// <param name="iteratorParams">Параметры итератора</param> /// <returns>Итератор для перебора событий</returns> private IEnumerable <EventRecord> GetEventsRundown(EventIteratorParams iteratorParams) { var logsIterator = new LogsIterator(_storageNamePredicate); var totalRead = 0; // перебираем логи в порядке убывания даты foreach (var helper in logsIterator.StreamedLogsRundown( iteratorParams.FromDate, iteratorParams.ToDate)) { // читаем лог с конца, для позиционирования в логе используем индекс // чтение выполняем блоками по _reverseBlockSize событий // определяем количество итераций по текущему логу var iterationsCount = helper.Index.RecordCount / _reverseBlockSize; if (helper.Index.RecordCount % _reverseBlockSize > 0) { iterationsCount++; } if (iterationsCount == 0) { // пустой лог continue; } for (var i = 0L; i < iterationsCount; i++) { // флаг принудительной остановки чтения лога, если он не дописан var stopReadThisLog = false; // определяем индекс первой записи в блоке (начинается с нуля) var firstRecordOfBlock = helper.Index.RecordCount - (i + 1) * _reverseBlockSize; // и число событий, которые нужно считать var eventsToRead = _reverseBlockSize; if (firstRecordOfBlock < 0) { // если попали сюда, это означает, что число записей в логе // не кратно _reverseBlockSize и нужно уточнить eventsToRead: eventsToRead = _reverseBlockSize + firstRecordOfBlock; // номер первой записи в этом случае равен нулю: firstRecordOfBlock = 0; } // переходим к нужному куску индексированных данных helper.Index.Seek(firstRecordOfBlock); // читаем очередной блок записей var bufferedEvents = new EventRecord[eventsToRead]; try { // флаг принудительного поиска по логу var seekInLog = true; for (var j = 0L; j < eventsToRead; j++) { // определяем индексированные данные очередной записи var currentIndex = helper.Index.GetNext(); if (seekInLog) { // устанавливаем смещение в логе на начало очередной записи helper.Reader.Seek(currentIndex.Offset, SeekOrigin.Begin); seekInLog = false; } // читаем очередное сообщение for (var k = 0; k < currentIndex.LinesCount; k++) { var storageEntry = EventRecordHelper.GetRawEntry( helper.Reader.ReadLine()); if (!iteratorParams.SourceFilter.Contains(storageEntry[3].TrimEnd()) || !iteratorParams.EventTypeFilter.Contains(storageEntry[4].TrimEnd())) { // прерываем чтение этого сообщения и взводим флаг принудительного // поиска по логу seekInLog = true; break; } if (bufferedEvents[j] == null) { bufferedEvents[j] = EventRecordHelper.CreateFromStorageEntry( storageEntry); } else { bufferedEvents[j].Text.Add(storageEntry[5]); } } } } catch (IndexOutOfRangeException) { // попали в недописанный кусок лога stopReadThisLog = true; } // разворачиваем блок записей Array.Reverse(bufferedEvents); // возвращаем записи как результат работы итератора foreach (var eventRecord in bufferedEvents) { if (eventRecord == null) { // пропускаем события, не попавшие под фильтр continue; } // возвращаем событие yield return(eventRecord); // увеличиваем счетчик событий totalRead++; // достигли максимального количества событий if (totalRead == iteratorParams.MaxEvents) { yield break; } } if (stopReadThisLog) { break; } } } }
/// <summary> /// Перебирает события в логах /// </summary> /// <param name="iteratorParams">Параметры итератора</param> /// <returns>Итератор для перебора событий</returns> private IEnumerable<EventRecord> GetEventsRundown(EventIteratorParams iteratorParams) { var logsIterator = new LogsIterator(_storageNamePredicate); var totalRead = 0; // перебираем логи в порядке убывания даты foreach (var helper in logsIterator.StreamedLogsRundown( iteratorParams.FromDate, iteratorParams.ToDate)) { // читаем лог с конца, для позиционирования в логе используем индекс // чтение выполняем блоками по _reverseBlockSize событий // определяем количество итераций по текущему логу var iterationsCount = helper.Index.RecordCount / _reverseBlockSize; if (helper.Index.RecordCount % _reverseBlockSize > 0) iterationsCount++; if (iterationsCount == 0) // пустой лог continue; for (var i = 0L; i < iterationsCount; i++) { // флаг принудительной остановки чтения лога, если он не дописан var stopReadThisLog = false; // определяем индекс первой записи в блоке (начинается с нуля) var firstRecordOfBlock = helper.Index.RecordCount - (i + 1) * _reverseBlockSize; // и число событий, которые нужно считать var eventsToRead = _reverseBlockSize; if (firstRecordOfBlock < 0) { // если попали сюда, это означает, что число записей в логе // не кратно _reverseBlockSize и нужно уточнить eventsToRead: eventsToRead = _reverseBlockSize + firstRecordOfBlock; // номер первой записи в этом случае равен нулю: firstRecordOfBlock = 0; } // переходим к нужному куску индексированных данных helper.Index.Seek(firstRecordOfBlock); // читаем очередной блок записей var bufferedEvents = new EventRecord[eventsToRead]; try { // флаг принудительного поиска по логу var seekInLog = true; for (var j = 0L; j < eventsToRead; j++) { // определяем индексированные данные очередной записи var currentIndex = helper.Index.GetNext(); if (seekInLog) { // устанавливаем смещение в логе на начало очередной записи helper.Reader.Seek(currentIndex.Offset, SeekOrigin.Begin); seekInLog = false; } // читаем очередное сообщение for (var k = 0; k < currentIndex.LinesCount; k++) { var storageEntry = EventRecordHelper.GetRawEntry( helper.Reader.ReadLine()); if (!iteratorParams.SourceFilter.Contains(storageEntry[3].TrimEnd()) || !iteratorParams.EventTypeFilter.Contains(storageEntry[4].TrimEnd())) { // прерываем чтение этого сообщения и взводим флаг принудительного // поиска по логу seekInLog = true; break; } if (bufferedEvents[j] == null) bufferedEvents[j] = EventRecordHelper.CreateFromStorageEntry( storageEntry); else bufferedEvents[j].Text.Add(storageEntry[5]); } } } catch (IndexOutOfRangeException) { // попали в недописанный кусок лога stopReadThisLog = true; } // разворачиваем блок записей Array.Reverse(bufferedEvents); // возвращаем записи как результат работы итератора foreach (var eventRecord in bufferedEvents) { if (eventRecord == null) // пропускаем события, не попавшие под фильтр continue; // возвращаем событие yield return eventRecord; // увеличиваем счетчик событий totalRead++; // достигли максимального количества событий if (totalRead == iteratorParams.MaxEvents) yield break; } if (stopReadThisLog) break; } } }