1

Тема: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

Добрый день!
Скажите, можно ли настроить синхронный вывод в файл логов, отправленных через  PrintDbgStr и как поведет себя эта функция при запуске нескольких скриптов одновременно? Или же надо в каждом скрипте настраивать вывод в лог-файл ручками, по сути минуя PrintDbgStr?

2 (2015-04-30 16:38:24 отредактировано admin)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

PrintDbgStr просто отправляет сообщение.
Чтобы это сообщение куда-то попало (на экран, в файл или еще куда) - надо устроить "ловушку". Ловушкой может выступать отдельная программа,  в примере выше - это программа DebugView.
При этом отправлять сообщения из разных скриптов через PrintDbgStr - можно без проблем. Но волшебно они ни в какой файл попадать не будут, пока не спущена какая-либо спец. программа, которая эти сообщения будет принимать.

Если вы опишете более подробно ту задачу, которую вы хотите решить, при этом уточните, что значит слово "синхронный вывод в файл", то может будет покумекать над адекватными средствами.


admin: работа с функцией PrintDbgStr описана в отдельной теме форума.

3 (2015-04-30 16:36:37 отредактировано admin)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

polygon, в первом сообщение топика про PrintDbgStr написано:

Условно-плохо то, что эта функция не годится для логирования: если в момент её вызова в системе нет "приёмника сообщений" - то выведенные сообщения нигде не сохранятся.

4

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

admin пишет:

polygon, вы почитайте первое сообщение этого топика, там написано:

Условно-плохо то, что эта функция не годится для логирования: если в момент её вызова в системе нет "приёмника сообщений" - то выведенные сообщения нигде не сохранятся.

Действительно, просмотрел.

swerg, самый простой способ я вижу - это записывать строки в файл. Через скрипт. То есть вместе с выводом в окно отдельно функцию вывода в файл. Поищу готовые сборки, чтоб хотя бы понять как правильно логи пишутся, чтобы потом не переделывать.
Дело в том, что помнится мне, квик мог в свое время глючить во время доступа к файлу. Если он занят еще кем-то. А мне не хотелось бы делать в скрипте двойную работу - сначала принт для отладки и проверки в скайте, потом PrintDbgStr чтобы отладить в квике, потом еще докручивать вывод в файл.. Громоздко получится.
Вот и думал, может есть надстройка для DebugView которая подхватывала бы сообщения и в файл их кидала.

5 (2015-04-28 23:16:09 отредактировано swerg)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

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

"Надстройку" сделать очень просто:

DEBUG_MODE = 2
-- DEBUG_MODE можно установить в одно из трёх значений:
--   0 - вывод через PrintDbgStr, вариант отлаженного робота
--   1 - вывод в файл, тестовые варианты
--   2 - вывод в окно сообщений терминала QUIK, отладочный вариант


-- в начало скрипта помещаем переопределение для PrintDbgStr()
_PrintDbgStr = PrintDbgStr
function PrintDbgStr(s)
    if DEBUG_MODE == 0 then
        _PrintDbgStr(s)
    else if DEBUG_MODE == 1 then
        LogToFile(s) -- реализация вывода в файл, примеры есть
    else
        message(s,0)
    end
    end
end

-- вывод отладочной информации из нашего робота 
-- в зависимости от значения настройки DEBUG_MODE

PrintDbgStr("12345")

6

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

Да, типа этого и пишу.
А Вы не знаете какую-нибудь утилитку, которая может на лету показывать содержимое нескольких файлов?
Я нашел MultiTail, но она, судя по всему под линукс. А так было бы идеально, если она может подхватывать несколько файлов и в одному разделенном окне показывать их содержимое. Там даже заявлена функция обработки рег. выражений и выполнение по ним действий. Для Windows пока найти не могу.

7

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

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

8

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

Да, согласен, не обозначил, что значит "на лету". Открываю прогу, подцепляю файлы, и вижу в реалтайме их содержимое, которое меняется. Если открою в блокноте, то файл будет занят, изменений не увижу да и поди квик ругнется что не смог записать. Хочу как в окне DebugView в реалтайме отслеживать содержимое файлов логов.  Если, конечно, такое возможно.

9 (2015-04-29 07:31:09 отредактировано swerg)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

Я лично пользуюсь Far manager.
Мне он привычнее (особенно то, что есть консоль), и файлы он обновляет при их изменении в режиме просмотра.
Хочется несколько файлов смотреть - несколько Far'ов открываю.

Опять же нагуглить просмотрщики логов для Windows - не проблема совсем )
То, что с ходу попалось:
Tail for Win32
LogViewer Pro 2.2.0

10

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

polygon пишет:

Да, согласен, не обозначил, что значит "на лету". Открываю прогу, подцепляю файлы, и вижу в реалтайме их содержимое, которое меняется. Если открою в блокноте, то файл будет занят, изменений не увижу да и поди квик ругнется что не смог записать. Хочу как в окне DebugView в реалтайме отслеживать содержимое файлов логов.  Если, конечно, такое возможно.

-записываем очередной лог в файл.
-тут же проверяем наличие этой записи в файле (по дата/тайм метке)
-если открытие файла не прошло - повторяем на след. итерации после прерывания
-если запись лога не прошла (файл занят и т.д.) повторяем на след. итерации после прерывания
-если запись лога не прошла раз 10 - привлекаем внимание алармом
-если запись прошла, считываем все логи в переменную-таблицу и обновляем окно qvcl.Memo (не метод Add, а именно через переменную, так геометрически быстрее вывод в Memo)

я так делаю, Вам подойдёт?
кстати все рабочие обменные и лог-файлы на RAM-диске.

11 (2015-04-29 14:04:23 отредактировано swerg)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

GREEN_X5 пишет:

-записываем очередной лог в файл.
-тут же проверяем наличие этой записи в файле (по дата/тайм метке)
-если открытие файла не прошло - повторяем на след. итерации после прерывания
-если запись лога не прошла (файл занят и т.д.) повторяем на след. итерации после прерывания
-если запись лога не прошла раз 10 - привлекаем внимание алармом

По-моему, это какой-то накладный очень алгоритм и избыточный, особенно "-тут же проверяем наличие этой записи в файле (по дата/тайм метке)". Даже для RAM-дисков.

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

Тогда получается: нам главное корректно обработать открытие файла на запись, если он открылся - то дальше просто пишем в него и пишем что надо. А значит всю логику обработки ошибок можно сосредоточить  лишь в той части, где мы открываем файл лога на запись.
И обработка мне видится такой:
- открыли файл на запись. Возникла проблема (это мы можем проверить) - изменили имя (log01.log); попробовали открыть файл с новым именем; не удалось - сделали имя log02.log и так до тех пор, пока не удастся открыть файл для лога.

12

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

swerg, да, перестраховки здесь есть. Это на случай совместного использования файла несколькими приложениями.

13 (2015-04-29 18:20:14 отредактировано polygon)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

swerg, Tail запускал, довести его до рабочего состояния не получилось, и, по-моему, он был платный. Понятно, что во все нужно вникать, разбираться, за все платить и т.д. но мне кажется, что задача простая - показать что есть. И если времени уходит много, надо искать другой продукт. Еще пробовал один, та же история. Конечно, нагуглить можно много чего, тут вопрос в том, кто что использует, для того и вопрос задавался. Может действительно, поставлю фар, вспомню досовское детство, тем более что он и DN до сих пор как память в архиве лежат)))

Уже слышал, что квик может подвиснуть если файл, который он пытается открыть занят другим приложением. Или нет, там вэлс 4 подвисал и не мог команду в три файл выдать, когда квик к нему обращался.
В общем, если кто-то что-то использует для просмотров на лету нескольких файлов, буду рад инфе, а пока довожу скрипт до ума. Вроде сделал, а квик не подключил socket, заругался, хоть я и файлы добавил.. Буду обходить. К стати, не знаете, есть в стандартных функциях луа вывод времени с миллисекундами? Мне пока что не нужно, срипт мой далеко не скорострельный по сути, но на будущее пригодится.

FAR рулит! по F3 замечательно выводит. Конечно, без доп. плюшек, но уже хорошо. Спасибо, swerg!

14

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

swerg пишет:

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

Тогда получается: нам главное корректно обработать открытие файла на запись, если он открылся - то дальше просто пишем в него и пишем что надо. А значит всю логику обработки ошибок можно сосредоточить  лишь в той части, где мы открываем файл лога на запись.

Этого не достаточно. Можете поэкспериментировать с файлом info.ini  smile , сделав следующее:
Запускаете скрипт, который пишет в файл. В это время открываете меню "Настройки - Основные..." В открывшемся окне нажмите "ОК". На некоторое время файл блокируется квиком и запись проходит с ошибками.

function main()
  local n = 0
  while not stopped do
    local file, err = io.open(getWorkingFolder()..'\\info.ini', 'a')
    if not file then PrintDbgStr(err)
    else
      n = n + 1
      file:write(tostring(n))
      file:flush()
    end
    file:close()
    sleep(1000)
  end
end

15

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

CyberTrader,
в вашем скрипте используется другой подход относительно того, который я описал. Вы постоянно открываете и закрываете файл лога, что неправильно, т.к. эти операции очень затратны.
Файл лога надо открыть один раз в начале скрипта и закрыть по завершении. Тогда, после того, как мы успешно открыли файл на запись, никакая программа уже не сможет нам помешать в него писать (возможно сама программа при этом не сможет записать в этот файл, но и ладно, это её проблемы, да и нехорошо это писать в один файл из двух разных программ, ничего хорошего из этого не получится).

16

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

polygon пишет:

swerg, Tail запускал, довести его до рабочего состояния не получилось, и, по-моему, он был платный. Понятно, что во все нужно вникать, разбираться, за все платить и т.д. но мне кажется, что задача простая - показать что есть. И если времени уходит много, надо искать другой продукт. Еще пробовал один, та же история. Конечно, нагуглить можно много чего, тут вопрос в том, кто что использует, для того и вопрос задавался. Может действительно, поставлю фар, вспомню досовское детство, тем более что он и DN до сих пор как память в архиве лежат)))

Уже слышал, что квик может подвиснуть если файл, который он пытается открыть занят другим приложением. Или нет, там вэлс 4 подвисал и не мог команду в три файл выдать, когда квик к нему обращался.
В общем, если кто-то что-то использует для просмотров на лету нескольких файлов, буду рад инфе, а пока довожу скрипт до ума. Вроде сделал, а квик не подключил socket, заругался, хоть я и файлы добавил.. Буду обходить. К стати, не знаете, есть в стандартных функциях луа вывод времени с миллисекундами? Мне пока что не нужно, срипт мой далеко не скорострельный по сути, но на будущее пригодится.

FAR рулит! по F3 замечательно выводит. Конечно, без доп. плюшек, но уже хорошо. Спасибо, swerg!

Про плюшки мои пять копеек...
http://i.imgur.com/sHa7zeN.png
ConEmu - http://www.conemu.ru/
Cygwin - https://www.cygwin.com/
В комплекте получаете удобную консоль, нормальный tail, grep и все что надо.
На скриншоте mc в консоли cygwin, но ConEmu отлично заточен под Far

17 (2015-04-30 11:54:34 отредактировано GREEN_X5)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

swerg пишет:

Файл лога надо открыть один раз в начале скрипта и закрыть по завершении.

Интересный подход, нужно попробовать...
А что будет в случае аварийного вылета скрипта или терминала? Для оси файл так и останется "открытым для записи" для некоего уже несуществующего клиента, или ось разруливает ситуацию в исходное состояние?

18

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

Для оси файл так и останется "открытым для записи" для некоего уже несуществующего клиента, или ось разруливает ситуацию в исходное состояние?

Конечно разруливает. По завершении процесса в ОС все связанные с ним ресурсы освобождаются, в том числе и закрываются открытые файлы, сетевые подключения и т.д. Иначе файловая система гарантированно умирала бы за 1..2 дня работы )

А что будет в случае аварийного вылета скрипта или терминала?

Тут есть момент:
1) Завершение скрипта (аварийное, т.е. остановка по ошибке) - это не завершение процесса QUIK с точки зрения ОС, поэтому в этом случае файл, возможно, останется залоченным до перезапуска QUIK.
2) Падение терминала - это завершение процесса с точи зрения ОС, поэтому файл будет разлочен.

Но если в результате аварийного завершения скрипта или терминала мы не выполнили file:close(), то, возможно, будет потеряна финальная часть лога, начиная с последнего вызова file:flush() (если вы сообще его вызываем). Это как бы аргумент в пользу использования file:flush() после каждой записи в файл, но тут, как водится, снова подвох: вызов file:flush() замедляет работу скрипта, т.к. производится сброс закэшированных ОС данных на винчестер, а устройство это - самое медленное в компьютере. Нас, конечно, несколько спасает аппаратный кэш внутри самого винчестера.

19 (2015-04-30 18:05:07 отредактировано CyberTrader)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

swerg пишет:

1) Завершение скрипта (аварийное, т.е. остановка по ошибке) - это не завершение процесса QUIK с точки зрения ОС, поэтому в этом случае файл, возможно, останется залоченным до перезапуска QUIK.

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

swerg пишет:

CyberTrader,
в вашем скрипте используется другой подход относительно того, который я описал. Вы постоянно открываете и закрываете файл лога, что неправильно, т.к. эти операции очень затратны.
Файл лога надо открыть один раз в начале скрипта и закрыть по завершении. Тогда, после того, как мы успешно открыли файл на запись, никакая программа уже не сможет нам помешать в него писать

Сейчас проверил: если файл открыт на запись до блокировки Квиком, то, да, при успешном закрытии файла, данные в нём сохраняются.
Если же файл открыт, будучи уже заблокированным Квиком, те данные, что сбрасывались на диск в момент блокировки будут потеряны. При этом открытие функцией io.open() проходит без ошибок.

Но мой скрипт наглядно показывает то, что файл при блокировании другим приложением может быть открыт без ошибок (причём, несколько раз!), при этом запись в него может быть невозможна.
Поэтому отсутствие ошибки "Permission denied" при открытии файла не гарантирует впоследствии успешной записи в него.

20 (2016-09-29 11:32:40 отредактировано sam063rus)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

-

21

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

Подскажите плиз. Как объявлять файл для лога с именем, содержащем текущую дату? Можно на этом примере:

file=io.open("D:\\Program Files\\Lua\\1\\logo.txt", "w") 

22 (2015-08-19 09:23:50 отредактировано kalikazandr)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

ascerdfg пишет:

Подскажите плиз. Как объявлять файл для лога с именем, содержащем текущую дату?

Сократите путь до вашего файла:

local path=getScriptPath()--"C:\\00LUA" - папка со скриптами
local file_name=path.."\\"..getInfoParam ("TRADEDATE").."_logo.txt"

23 (2015-09-07 13:49:02 отредактировано ascerdfg)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

.

24 (2015-09-07 13:49:15 отредактировано ascerdfg)

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

.

25

Re: Запись логов в файл из Lua-скриптов, PrintDbgStr для логирования

ascerdfg пишет:

Единственное что Квик перестал ругаться при его закрытии.

Какая-то ошибка в скрипте мне видится, как таковое применение flush не может влиять на закрытие.