resource
Молодой специалист
Offline
Пол:
|
|
« : 13-03-2010 09:28 » |
|
Здравствуйте друзья. Не думал, что когда-нибудь доживу до такого вопроса, но так случилось Есть задача. Приложение получает данные извне и пишет их в лог. Задача решена как обычно. Т.е. задается максимальный размер лог-фала, и если он превышен, то файл закрывается (с записанными данными) и создается следующий файл и т.д.. Но вот возникла такая вариция на тему. Что если лог-файл должен быть один. Причем таким образом: если файл "полный" (достиг макимального заданного размера), то самая "старая" запись (из начала) файла удаляется, а новая приписывается (в конец). Так обычно делается если лог ведется в окно, в какой-нибудь лист-контрол. Но тут то файл, а не контрол. Данные структирированы, но для простоты можно считать, что каждая запись это обычная строка текста. Необязательно удалять и тут же записывать и менно по одной строке, пусть это даже будет несколько строк. Вариантов, если честно, никаких. Неужели каждый раз при удалении/добавлении одной записи (при "полном" файле) создавать новый файл и почти что дублировать в нем содержимое предыдущего файла. Если размер файла, к примеру мегабайт 50, то получится как-то не очень красиво (в плане быстродействия). Вот если бы можно было мапить не файл на память, а память на файл Но если серьезно, есть ли тут какие-то варианты кроме как тупо создать новый файл, скопировать в него содержимое предыдущего (за исключением одной или нескольких строк) и дописать новую строку (или несколько)?
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #1 : 13-03-2010 09:44 » |
|
Других способов нет, при условии, что возможно меть только один лог файл. если их временно можно хранить несколько или если можно, например, на какое-то время превышать установленный максимальный размер, или возможно хранить не полный лог (т.е. по достижении 50Мб обрезать скажем половину, а не только первую строку)
|
|
|
Записан
|
С уважением Lapulya
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #2 : 13-03-2010 10:17 » |
|
resource, если использовать для хранения логов БД, то управление упростится. Например, sqlite3.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #3 : 13-03-2010 10:26 » |
|
Насчет если их временно можно хранить несколько по достижении 50Мб обрезать скажем половину, а не только первую строку Временно можно хранить сколько угодно. Вопрос в том, о каком промежутке времени идет речь. Ведь файл в любой момент могут открыть и прочитать. Я конечно допускаю, что в любом случае будет что-то теряться, но смотря на сколько (по времени) и сколько (объем данных). А 25 метров (если отталкиваться от вышепредложенного) это довольно нехилый объем информации. И что еще важно, я не могу делать никаких предположений о скорости наполнения лога. Т.е. может и за 5 секунд 50 метров набраться, а может и за 5 минут - неизвестно. если использовать для хранения логов БД, то управление упростится рационально, но базу я не могу себе позволить.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #4 : 13-03-2010 10:39 » |
|
Почему?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Serg79
|
|
« Ответ #5 : 13-03-2010 10:39 » |
|
resource, используй те методы которые используют все программы которые активно ведут логи своих действий.
Например Apache и Squid поступают примерно следующим образом: при получении сигнала о сохранении лог-файла программа закрывает свой лог-файл (file.log), переименовывает его (file.log -> file.log.1), и открывает новый файл на запись (file.log).
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #6 : 13-03-2010 10:45 » |
|
Serg79, немного не так: внешний периодический сервис сперва ротирует файлы, а потом посылает команду Апачу/Сквиду закрыть файл и открыть снова. Но можно и самостоятельно ротировать, без внешнего помощника.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #7 : 13-03-2010 10:46 » |
|
Почему? Будем считать это как условие. Serg79, я изначально написал, что так и делаю. Это просто вариация на тему, смогу - не смогу, возможно - невозмозможно. Был еще такой вариант. Выделить память под лог-буфер. Буфер - кольцо, что позволит добавлять записи без заморочек. Сделать одтельный поток, который будет переодически перемещать буфер (целиком) в файл (напрямую или через мапинг - суть не в этом). Но тут встало две проблемы: 1. синхронизация. блокировать весь буфер размером, например в 100 метров, это как-то по-варварски. в него ведь писАть не смогут 2. ресурсы. ведь размер лога может быть и 500 метров и Гиг и даже не один Гиг. Выделять память таких размеров как-то "не кашерно" Поэтому вариант как-то отсёкся сам собой.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #8 : 13-03-2010 10:48 » |
|
resource, как вариант: сделать записи в логе фиксированного размера: попросту перезаписывай их по кольцу.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Sla
|
|
« Ответ #9 : 13-03-2010 10:52 » |
|
можно использовать типизированный файл и индекс + буферы
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #10 : 13-03-2010 10:53 » |
|
RXL, ну случай описан предыдущим постом. Думаю получился просто асинхронный постинг Sla, довольно абстрактно
|
|
« Последнее редактирование: 13-03-2010 10:56 от resource »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #11 : 13-03-2010 10:56 » |
|
resource, я его видел, но там у тебя о кольце в памяти, а не в файле. Даже если его мапировать в память, в чем особой нужды нет, то на сброс пойдут только измененные блоки, а не весь файл.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #12 : 13-03-2010 10:57 » |
|
Sla, этак мы возвращаемся к БД...
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Sla
|
|
« Ответ #13 : 13-03-2010 11:01 » |
|
Задача Организовать запись логов в файл по принципу - первый зашел - первый вышел (очередь)
Вариант решения Типизированный файл Индекс файл Буфер логов (для уменьшения количества перезаписей)
Недостатки - ограничение строки лога оперативность просмотра (нужно ждать последний блок из буфера)
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
Sla
|
|
« Ответ #14 : 13-03-2010 11:01 » |
|
RXL, ну да, т.е. что-то свое
|
|
|
Записан
|
Мы все учились понемногу... Чему-нибудь и как-нибудь.
|
|
|
zubr
Гость
|
|
« Ответ #15 : 13-03-2010 11:06 » |
|
1. Сместил указатель файла от начала на величину первой записи. 2. Прочитал в буфер (чем буфер больше - тем быстрее будет работать). 3. Сместил указатель на начало - записал буфер в файл. 4. Сместил указатель на размер записи + размер буфера - прочитал в буфер. И т. д. до конца файла.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #16 : 13-03-2010 11:08 » |
|
К примеру, ядро Linux логирует в кольцевой буфер в памяти, но в файле это может оказаться только с помощью другого процесса, который периодически читает новые записи из буфера и пишет в файл. Но опять же - кольцо в файле организовать сложнее, чем в памяти: либо фиксированные записи. либо сложная система управления свободным местом и индексация.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #17 : 13-03-2010 11:10 » |
|
там у тебя о кольце в памяти, а не в файле Хотелось бы чтоб лог можно было открывать в любой момент текстовым редактором и видеть записи в нормальном порядке (по принципу очереди), а не в кольцевом. Sla, этак мы возвращаемся к БД... Да, так и есть. Это не подходит. zubr ну это всё долго будет происходить. Особенно если лог размером от Гига Думаю, что приемлемого решения для такой задачи всё таки не существует Спасибо всем за предложения
|
|
« Последнее редактирование: 13-03-2010 11:12 от resource »
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #18 : 13-03-2010 11:15 » |
|
resource, тогда выхода всего два: либо много файлов и ротация, либо один большой файл и каждый раз его перезаписывать целиком.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
Serg79
|
|
« Ответ #19 : 13-03-2010 14:54 » |
|
RXL, ну squid в дефолтных настройках весь цикл ротации и удаления старых файлов сам производит, он только ждет сигнала.
|
|
|
Записан
|
|
|
|
Антон (LogRus)
|
|
« Ответ #20 : 15-03-2010 05:13 » |
|
resource, мой любимы вопрос А за чем? Какая при этом преследуется цель? Бизнес-требование? Требование к эргономике системы? кстати размер логов можно сильно уменьшить, если поток данных в файл, гнать через библиотеку архивации, например, zlib.
|
|
|
Записан
|
Странно всё это....
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #21 : 15-03-2010 06:36 » |
|
LogRus, Хотелось бы чтоб лог можно было открывать в любой момент текстовым редактором и видеть записи в нормальном порядке (по принципу очереди), а не в кольцевом. Компрессия отменяется
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #22 : 15-03-2010 07:54 » |
|
LogRusЭто просто вариация на тему, смогу - не смогу, возможно - невозмозможно Если угодно, это из серии гимнастики для мозга. Хотя еслиб это реально можно было сделать, то грех было бы не попробовать. Просто подумал - вдруг это как-то можно, а я ведь не знаю как. Ведь учиться всегда полезно. Ну а в реальной практике я конечно пользуюсь обычным методом - задаю макс. размер лога и когда он его достиг, создаю новый файл (об этом я изначально написал).
|
|
|
Записан
|
|
|
|
Вад
|
|
« Ответ #23 : 15-03-2010 22:05 » |
|
Если требуется сделать красиво - то нужно написать свой вьюер для лога, и дальше делать с логом что угодно, хоть в трубочку сворачивать Потому что вьюер будет знать, из чего и как в любой момент времени собирать лог при просмотре. Но, разумеется, это не поможет, если целевой пользователь софта - админ, привыкший ходить руками в папку с логами (или если платформа Linux, что примерно равносильно - нехорошо нарушать традиции).
|
|
|
Записан
|
|
|
|
lapulya
Молодой специалист
Offline
|
|
« Ответ #24 : 24-03-2010 22:32 » |
|
resourceВременно можно хранить сколько угодно. Вопрос в том, о каком промежутке времени идет речь. Ведь файл в любой момент могут открыть и прочитать. Я конечно допускаю, что в любом случае будет что-то теряться, но смотря на сколько (по времени) и сколько (объем данных). А 25 метров (если отталкиваться от вышепредложенного) это довольно нехилый объем информации. И что еще важно, я не могу делать никаких предположений о скорости наполнения лога. Т.е. может и за 5 секунд 50 метров набраться, а может и за 5 минут - неизвестно. Честно говоря я не понял, что именно не устроило... Промежуток времени выбирается как раз исходя из необходимой производительности (можно раз в 5 минут, можно раз в день и т.д.), но в любом случае если мы записали 50 метров в первый файл и во временный файл также записали 50 метров, то первый файл можно затереть + считать временный первым (основным) + начать писать в новый временный, так что тут все нормально. Скорость наполнения лога рояли не играет. Писать же в кольцо сформированное в памяти - это не лог, а труба, потому как при падении программы вы просто останетесь у разбитого корыта. Необходимо каждую запись обязательно сбрасывать в файл (тогда вы лишаетесь максимум последней записи, ну или если пишется в отдельном потоке, то нескольких... хотя возможно и самых важных, но от этого уже не уйти ))) )
|
|
|
Записан
|
С уважением Lapulya
|
|
|
|