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

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

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

« : 13-03-2010 09:28 » 

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

Есть задача. Приложение получает данные извне и пишет их в лог. Задача решена как обычно. Т.е. задается максимальный размер лог-фала, и если он превышен, то файл закрывается (с записанными данными) и создается следующий файл и т.д..

Но вот возникла такая вариция на тему. Что если лог-файл должен быть один. Причем таким образом: если файл "полный" (достиг макимального заданного размера), то самая "старая" запись (из начала) файла удаляется, а новая приписывается (в конец). Так обычно делается если лог ведется в окно, в какой-нибудь лист-контрол. Но тут то файл, а не контрол.
Данные структирированы, но для простоты можно считать, что каждая запись это обычная строка текста. Необязательно удалять и тут же записывать и менно по одной строке, пусть это даже будет несколько строк.
Вариантов, если честно, никаких. Неужели каждый раз при удалении/добавлении одной записи (при "полном" файле) создавать новый файл и почти что дублировать в нем содержимое предыдущего файла. Если размер файла, к примеру мегабайт 50, то получится как-то не очень красиво (в плане быстродействия). Вот если бы можно было мапить не файл на память, а память на файл  Улыбаюсь Но если серьезно, есть ли тут какие-то варианты кроме как тупо создать новый файл, скопировать в него содержимое предыдущего (за исключением одной или нескольких строк) и дописать новую строку (или несколько)?
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #1 : 13-03-2010 09:44 » 

Других способов нет, при условии, что возможно меть только один лог файл. если их временно можно хранить несколько или если можно, например, на какое-то время превышать установленный максимальный размер, или возможно хранить не полный лог (т.е. по достижении 50Мб обрезать скажем половину, а не только первую строку)
Записан

С уважением Lapulya
RXL
Технический
Администратор

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

WWW
« Ответ #2 : 13-03-2010 10:17 » 

resource, если использовать для хранения логов БД, то управление упростится. Например, sqlite3.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
resource
Молодой специалист

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

« Ответ #3 : 13-03-2010 10:26 » 

Насчет
Цитата: lapulya
если их временно можно хранить несколько
Цитата: lapulya
по достижении 50Мб обрезать скажем половину, а не только первую строку

Временно можно хранить сколько угодно. Вопрос в том, о каком промежутке времени идет речь. Ведь файл в любой момент могут открыть и прочитать. Я конечно допускаю, что в любом случае будет что-то теряться, но смотря на сколько (по времени) и сколько (объем данных). А 25 метров (если отталкиваться от вышепредложенного) это довольно нехилый объем информации. И что еще важно, я не могу делать никаких предположений о скорости наполнения лога. Т.е. может и за 5 секунд 50 метров набраться, а может и за 5 минут - неизвестно.
 
Цитата: RXL
если использовать для хранения логов БД, то управление упростится
рационально, но базу я не могу себе позволить.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #4 : 13-03-2010 10:39 » 

Почему?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

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

WWW
« Ответ #5 : 13-03-2010 10:39 » 

resource, используй те методы которые используют все программы которые активно ведут логи своих действий.

Например Apache и Squid поступают примерно следующим образом: при получении сигнала о сохранении лог-файла программа закрывает свой лог-файл (file.log), переименовывает его (file.log -> file.log.1), и открывает новый файл на запись (file.log).
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #6 : 13-03-2010 10:45 » 

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

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
resource
Молодой специалист

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

« Ответ #7 : 13-03-2010 10:46 » 

Цитата: RXL
Почему?
Будем считать это как условие.

Serg79, я изначально написал, что так и делаю. Это просто вариация на тему, смогу - не смогу, возможно - невозмозможно.

Был еще такой вариант. Выделить память под лог-буфер. Буфер - кольцо, что позволит добавлять записи без заморочек. Сделать одтельный поток, который будет переодически перемещать буфер (целиком) в файл (напрямую или через мапинг - суть не в этом). Но тут встало две проблемы:
1. синхронизация. блокировать весь буфер размером, например в 100 метров, это как-то по-варварски. в него ведь писАть не смогут
2. ресурсы. ведь размер лога может быть и 500 метров и Гиг и даже не один Гиг. Выделять память таких размеров как-то "не кашерно"
Поэтому вариант как-то отсёкся сам собой.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #8 : 13-03-2010 10:48 » 

resource, как вариант: сделать записи в логе фиксированного размера: попросту перезаписывай их по кольцу.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

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

WWW
« Ответ #9 : 13-03-2010 10:52 » 

можно использовать типизированный файл и индекс
+ буферы
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
resource
Молодой специалист

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

« Ответ #10 : 13-03-2010 10:53 » 

RXL, ну случай описан предыдущим постом. Думаю получился просто асинхронный постинг  Улыбаюсь

Sla, довольно абстрактно
« Последнее редактирование: 13-03-2010 10:56 от resource » Записан
RXL
Технический
Администратор

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

WWW
« Ответ #11 : 13-03-2010 10:56 » 

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

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

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

WWW
« Ответ #12 : 13-03-2010 10:57 » 

Sla, этак мы возвращаемся к БД...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

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

WWW
« Ответ #13 : 13-03-2010 11:01 » 

Задача
Организовать запись логов в файл по принципу  - первый зашел - первый вышел (очередь)

Вариант решения
Типизированный файл
Индекс файл
Буфер логов (для уменьшения количества перезаписей)

Недостатки - ограничение строки лога
оперативность просмотра (нужно ждать последний блок из буфера)
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

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

WWW
« Ответ #14 : 13-03-2010 11:01 » 

RXL, ну да, т.е. что-то свое
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
zubr
Гость
« Ответ #15 : 13-03-2010 11:06 » 

1. Сместил указатель файла от начала на величину первой записи.
2. Прочитал в буфер (чем буфер больше - тем быстрее будет работать).
3. Сместил указатель на начало - записал буфер в файл.
4. Сместил указатель на размер записи + размер буфера - прочитал в буфер.
И т. д. до конца файла.
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #16 : 13-03-2010 11:08 » 

К примеру, ядро Linux логирует в кольцевой буфер в памяти, но в файле это может оказаться только с помощью другого процесса, который периодически читает новые записи из буфера и пишет в файл. Но опять же - кольцо в файле организовать сложнее, чем в памяти: либо фиксированные записи. либо сложная система управления свободным местом и индексация.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
resource
Молодой специалист

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

« Ответ #17 : 13-03-2010 11:10 » 

Цитата: RXL
там у тебя о кольце в памяти, а не в файле
Хотелось бы чтоб лог можно было открывать в любой момент текстовым редактором и видеть записи в нормальном порядке (по принципу очереди), а не в кольцевом.

Цитата: RXL
Sla, этак мы возвращаемся к БД...
Да, так и есть. Это не подходит.

zubr ну это всё долго будет происходить. Особенно если лог размером от Гига

Думаю, что приемлемого решения для такой задачи всё таки не существует Жаль
Спасибо всем за предложения
« Последнее редактирование: 13-03-2010 11:12 от resource » Записан
RXL
Технический
Администратор

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

WWW
« Ответ #18 : 13-03-2010 11:15 » 

resource, тогда выхода всего два: либо много файлов и ротация, либо один большой файл и каждый раз его перезаписывать целиком.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

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

WWW
« Ответ #19 : 13-03-2010 14:54 » 

RXL, ну squid в дефолтных настройках весь цикл ротации и удаления старых файлов сам производит, он только ждет сигнала.
Записан
Антон (LogRus)
Глобальный модератор

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


WWW
« Ответ #20 : 15-03-2010 05:13 » 

resource, мой любимы вопрос Улыбаюсь А за чем? Какая при этом преследуется цель? Бизнес-требование? Требование к эргономике системы?

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

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

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

WWW
« Ответ #21 : 15-03-2010 06:36 » 

LogRus,

Хотелось бы чтоб лог можно было открывать в любой момент текстовым редактором и видеть записи в нормальном порядке (по принципу очереди), а не в кольцевом.

Компрессия отменяется Улыбаюсь
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
resource
Молодой специалист

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

« Ответ #22 : 15-03-2010 07:54 » 

LogRus
Цитата: resource
Это просто вариация на тему, смогу - не смогу, возможно - невозмозможно
Если угодно, это из серии гимнастики для мозга. Хотя еслиб это реально можно было сделать, то грех было бы не попробовать. Просто подумал - вдруг это как-то можно, а я ведь не знаю как. Ведь учиться всегда полезно.
Ну а в реальной практике я конечно пользуюсь обычным методом - задаю макс. размер лога и когда он его достиг, создаю новый файл (об этом я изначально написал).
Записан
Вад
Модератор

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

« Ответ #23 : 15-03-2010 22:05 » 

Если требуется сделать красиво - то нужно написать свой вьюер для лога, и дальше делать с логом что угодно, хоть в трубочку сворачивать Улыбаюсь Потому что вьюер будет знать, из чего и как в любой момент времени собирать лог при просмотре.

Но, разумеется, это не поможет, если целевой пользователь софта - админ, привыкший ходить руками в папку с логами (или если платформа Linux, что примерно равносильно - нехорошо нарушать традиции).
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #24 : 24-03-2010 22:32 » 

resource

Цитата
Временно можно хранить сколько угодно. Вопрос в том, о каком промежутке времени идет речь. Ведь файл в любой момент могут открыть и прочитать. Я конечно допускаю, что в любом случае будет что-то теряться, но смотря на сколько (по времени) и сколько (объем данных). А 25 метров (если отталкиваться от вышепредложенного) это довольно нехилый объем информации. И что еще важно, я не могу делать никаких предположений о скорости наполнения лога. Т.е. может и за 5 секунд 50 метров набраться, а может и за 5 минут - неизвестно.

Честно говоря я не понял, что именно не устроило...

Промежуток времени выбирается как раз исходя из необходимой производительности (можно раз в 5 минут, можно раз в день и т.д.), но в любом случае если мы записали 50 метров в первый файл и во временный файл также записали 50 метров, то первый файл можно затереть + считать временный первым (основным) + начать писать в новый временный, так что тут все нормально. Скорость наполнения лога рояли не играет.

Писать же в кольцо сформированное в памяти - это не лог, а труба, потому как при падении программы вы просто останетесь у разбитого корыта. Необходимо каждую запись обязательно сбрасывать в файл (тогда вы лишаетесь максимум последней записи, ну или если пишется в отдельном потоке, то нескольких... хотя возможно и самых важных, но от этого уже не уйти ))) )
Записан

С уважением Lapulya
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines