| 
			| 
					
						| resource 
								Молодой специалист    Offline 
								Пол:    | 
								|  | «  : 13-03-2010 09:28 »  |  | 
 
 Здравствуйте друзья.  Не думал, что когда-нибудь доживу до такого вопроса, но так случилось    Есть задача. Приложение получает данные извне и пишет их в лог. Задача решена как обычно. Т.е. задается максимальный размер лог-фала, и если он превышен, то файл закрывается (с записанными данными) и создается следующий файл и т.д.. Но вот возникла такая вариция на тему. Что если лог-файл должен быть один. Причем таким образом: если файл "полный" (достиг макимального заданного размера), то самая "старая" запись (из начала) файла удаляется, а новая приписывается (в конец). Так обычно делается если лог ведется в окно, в какой-нибудь лист-контрол. Но тут то файл, а не контрол. Данные структирированы, но для простоты можно считать, что каждая запись это обычная строка текста. Необязательно удалять и тут же записывать и менно по одной строке, пусть это даже будет несколько строк. Вариантов, если честно, никаких. Неужели каждый раз при удалении/добавлении одной записи (при "полном" файле) создавать новый файл и почти что дублировать в нем содержимое предыдущего файла. Если размер файла, к примеру мегабайт 50, то получится как-то не очень красиво (в плане быстродействия). Вот если бы можно было мапить не файл на память, а память на файл     Но если серьезно, есть ли тут какие-то варианты кроме как тупо создать новый файл, скопировать в него содержимое предыдущего (за исключением одной или нескольких строк) и дописать новую строку (или несколько)? |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| lapulya 
								Молодой специалист    Offline | 
								|  | « Ответ #1 : 13-03-2010 09:44 »  |  | 
 
 Других способов нет, при условии, что возможно меть только один лог файл. если их временно можно хранить несколько или если можно, например, на какое-то время превышать установленный максимальный размер, или возможно хранить не полный лог (т.е. по достижении 50Мб обрезать скажем половину, а не только первую строку) |  
						| 
								|  |  
								|  |  Записан | 
 
 С уважением Lapulya |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #2 : 13-03-2010 10:17 »  |  | 
 
 resource, если использовать для хранения логов БД, то управление упростится. Например, sqlite3. |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| resource 
								Молодой специалист    Offline 
								Пол:    | 
								|  | « Ответ #3 : 13-03-2010 10:26 »  |  | 
 
 Насчет   если их временно можно хранить несколько по достижении 50Мб обрезать скажем половину, а не только первую строку Временно можно хранить сколько угодно. Вопрос в том, о каком промежутке времени идет речь. Ведь файл в любой момент могут открыть и прочитать. Я конечно допускаю, что в любом случае будет что-то теряться, но смотря на сколько (по времени) и сколько (объем данных). А 25 метров (если отталкиваться от вышепредложенного) это довольно нехилый объем информации. И что еще важно, я не могу делать никаких предположений о скорости наполнения лога. Т.е. может и за 5 секунд 50 метров набраться, а может и за 5 минут - неизвестно.    если использовать для хранения логов БД, то управление упростится рационально, но базу я не могу себе позволить. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #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 | 
								|  | « Ответ #6 : 13-03-2010 10:45 »  |  | 
 
 Serg79, немного не так: внешний периодический сервис сперва ротирует файлы, а потом посылает команду Апачу/Сквиду закрыть файл и открыть снова. Но можно и самостоятельно ротировать, без внешнего помощника. |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| resource 
								Молодой специалист    Offline 
								Пол:    | 
								|  | « Ответ #7 : 13-03-2010 10:46 »  |  | 
 
 Почему? Будем считать это как условие.Serg79 , я изначально написал, что так и делаю. Это просто вариация на тему, смогу - не смогу, возможно - невозмозможно. Был еще такой вариант. Выделить память под лог-буфер. Буфер - кольцо, что позволит добавлять записи без заморочек. Сделать одтельный поток, который будет переодически перемещать буфер (целиком) в файл (напрямую или через мапинг - суть не в этом). Но тут встало две проблемы: 1. синхронизация. блокировать весь буфер размером, например в 100 метров, это как-то по-варварски. в него ведь писАть не смогут 2. ресурсы. ведь размер лога может быть и 500 метров и Гиг и даже не один Гиг. Выделять память таких размеров как-то "не кашерно" Поэтому вариант как-то отсёкся сам собой. |  
						| 
								|  |  
								|  |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #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 | 
								|  | « Ответ #11 :  13-03-2010 10:56 »   |  | 
 
 resource, я его видел, но там у тебя о кольце в памяти, а не в файле. Даже если его мапировать в память, в чем особой нужды нет, то на сброс пойдут только измененные блоки, а не весь файл. |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #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 | 
								|  | « Ответ #16 : 13-03-2010 11:08 »  |  | 
 
 К примеру, ядро Linux логирует в кольцевой буфер в памяти, но в файле это может оказаться только с помощью другого процесса, который периодически читает новые записи из буфера и пишет в файл. Но опять же - кольцо в файле организовать сложнее, чем в памяти: либо фиксированные записи. либо сложная система управления свободным местом и индексация. |  
						| 
								|  |  
								|  |  Записан | 
 
 ... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. |  |  | 
	| 
			| 
					
						| resource 
								Молодой специалист    Offline 
								Пол:    | 
								|  | « Ответ #17 : 13-03-2010 11:10 »  |  | 
 
 там у тебя о кольце в памяти, а не в файле Хотелось бы чтоб лог можно было открывать в любой момент текстовым редактором и видеть записи в нормальном порядке (по принципу очереди), а не в кольцевом. Sla, этак мы возвращаемся к БД... Да, так и есть. Это не подходит.zubr  ну это всё долго будет происходить. Особенно если лог размером от Гига Думаю, что приемлемого решения для такой задачи всё таки не существует   Спасибо всем за предложения |  
						| 
								|  |  
								| « Последнее редактирование: 13-03-2010 11:12 от resource » |  Записан | 
 |  |  | 
	| 
			| 
					
						| RXL | 
								|  | « Ответ #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 | 
								|  | « Ответ #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 |  |  | 
	|  |