Журналы и логи
Журналы
Журнал ошибок

Содержит все ошибки, возникшие в ходе работы. Ошибки делятся на следующие классы (колонка Класс объекта):
- ошибки, возникшие на сервере — отображены на белом фоне и входят в единственный класс
Исключение на сервере; - ошибки, возникшие на сервере и полученные клиентским приложением — отображены на розовом фоне и входят в единственный класс
Исключение на сервере (от клиента); - ошибки, возникшие на клиентском приложении — отображены на жёлтом фоне и входят в два класса:
Исключение на клиентеиИсключение на веб-клиенте; - ошибки связи — отображены на голубом фоне и входят в два класса:
Временное исключение связи— связь с сервером прерывалась, но была восстановлена;Постоянное исключение связи— связь с сервером прерывалась и не восстановилась.
В секции След исключения отображается java-стек ошибки, в секции LSF след исключения — lsfusion-стек, в секции Асинхронный след исключения — стек породившего асинхронного запроса (актуально для ошибок в фоновых потоках и в обработчиках событий, где обычный стек не показывает исходный пользовательский контекст).
Журнал подключений

Хранит информацию о пользователях, которые подключались к системе, с какого компьютера, каковы характеристики этого ПК, а также информацию о дате и времени подключения/отключения. На форме можно отобразить пользователей, работающих в данный момент с БД, — отметка Активные подключения.
В секции Форма видно, сколько раз и в какие формы входил пользователь. В секции Сессия, для некоторых форм, можно проследить, когда применялись изменения.
Журнал запусков

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

Содержит более подробную информацию о применённых изменениях, которые были отражены в Журнале подключений в секции Сессия. В колонке Изменения отображается список Свойств (колонок), в которых менялись значения, а также количество изменений (строк). Логируются только изменения на текущей форме — зависимые Свойства, которые меняются одновременно на других таблицах, в данный список не попадают.
По умолчанию список изменённых свойств не логируется — в колонке Изменения остаются только сводные счётчики; полное логирование включается настройкой logChangesSession.
На форме можно отфильтровать изменения, сделанные пользователями (без системных изменений), — отметка Только изменения пользователя.
Журнал клиентских приложений

Содержит информацию о качестве соединения во время работы с сервером приложений за определённый период времени.
В верхней части формы для клиентских компьютеров, помимо системных показателей памяти, можно проанализировать средние значения времени отклика (ping) в миллисекундах, доступной и используемой java-приложением памяти. Анализируемый период задаётся вводом Дата с и Дата по в секции Дата со временем. Кроме дат, здесь можно задать пороговые значения для этих же показателей (ping и память) — это позволит получить суммарное время (в секундах), когда клиентский ПК превышал пороговые значения.
В нижней части, на вкладке Данные, представлена хронология изменений времени отклика, доступной и используемой памяти. Эта информация отображается только для десктоп-клиента.
Время хранения журналов

Сколько должна храниться информация в перечисленных журналах, указывается на форме Администрирование > Настройки > вкладка Логирование.
Пользовательское логирование
Если необходимо отслеживать изменения отдельных значений в каких-либо Свойствах (колонках) на определённых Формах, для таких случаев разработан механизм пользовательского логирования. Например, в справочнике Сотрудники нужно протоколировать изменения фамилии сотрудника. Для этого:
-
находясь на любой записи колонки
Фамилия, по правой клавише мыши вызываем менюНастройка политики свойств:
-
в форме
Политика безопасностиустанавливаем отметкуЛогируется пользователеми нажимаем кнопкуОК:
-
после перезапуска сервера приложений при нажатии правой клавишей мыши на Свойстве
Фамилияпоявится дополнительный пункт менюПоказать историю изменений. Если для текущей записи фамилия была кем-то изменена, это найдёт отражение в истории изменения свойств:
Время хранения для подобных протоколов устанавливается одинаковым со временем хранения для Журнала изменений.
Механизм настройки журналов
Каждый из перечисленных журналов задаётся в системных модулях платформы единообразно: для журнала объявляется отдельный класс, форма для его просмотра, параметр времени хранения и точка расширения для очистки устаревших записей. Эта связка автоматически порождается на стороне системных модулей по одному и тому же шаблону, поэтому время хранения для каждого журнала задаётся независимо — на форме Администрирование > Настройки > Логирование каждому журналу соответствует своя строка.
Очистка устаревших записей выполняется по расписанию через общую точку расширения clearApplicationLog. Прикладной модуль может подключиться к этой точке и добавить свой журнал в общий цикл очистки, не дублируя планировщик.
Логи
Для каждого компонента платформы в платформе поддерживается следующий набор логов:
| Компонент | Папка | Логи |
|---|---|---|
| Сервер приложений (Server) | $FUSION_DIR$/logs, где $FUSION_DIR$ - папка запуска сервера приложений |
|
| Веб-сервер (Client) | $CATALINA_BASE$/logs, где $CATALINA_BASE$ - папка, в которую установлен Tomcat |
|
| Десктоп-клиент | $USER_DIR$/.fusion/logs, где $USER_DIR$ - папка пользователя |
|
При автоматической установке под Linux для этих папок (как и для файлов lsFusion параметров запуска) автоматически создаются symlink'и на другие папки, расположение которых лучше соответствует идеологии Linux.
Что попадает в логи
Многие из перечисленных серверных логов наполняются только тогда, когда для конкретного пользователя включен соответствующий режим диагностики - пользовательские признаки диагностики на вкладке логирования формы настроек. Перечисленные ниже рабочие параметры определяют, что именно и в каком объеме пишет каждый режим.
| Лог | Параметр | По умолчанию | Что определяет |
|---|---|---|---|
sql | logTimeThreshold | 60 мс | Пока для пользователя включено отладочное логирование (loggerDebugEnabled), его завершившийся запрос, выполнявшийся дольше этого времени, записывается вместе со стеком lsFusion и накопительными итогами по времени и количеству, которые ведутся на весь серверный процесс, а не на одно соединение; более быстрые только пополняют эти итоги. Запрос, завершившийся ошибкой, сюда не попадает вовсе, каким бы медленным он ни был |
explainexplaincompile | explainNoAnalyzeThreshold | 10000 мс | При включенном для пользователя режиме EXPLAIN ANALYZE (explainAnalyzeMode) запрос, оценочная стоимость которого превышает это значение, дополнительно объясняется до выполнения - обычным EXPLAIN (VERBOSE, COSTS), который его не выполняет, - чтобы план был получен, даже если реальное выполнение потом зависнет или будет прервано. Этот план записывается, только если запрос все еще выполняется спустя некоторое время или завершился ошибкой; при успешном завершении план отбрасывается, и остается обычный вывод по explainThreshold. 0 объясняет так каждый запрос |
explain | explainThreshold | 100 мс | При включенном для пользователя режиме EXPLAIN ANALYZE (Service.explainAnalyzeMode[User]) план его запроса записывается, если время планирования и выполнения по этому плану достигает порога; запрос на чтение для этого выполняется повторно под анализом, и только если его исходное выполнение тоже достигло порога, а команда изменения данных сразу выполняется под анализом. 0 отключает отбор по времени. В лог попадают только выполняемые SQL-команды, поэтому присваивание свойству само по себе в него не попадает: команда записи в таблицу свойства на месте присваивания не выполняется - изменение накапливается в сессии, а команда вместе с планом выполняется при применении изменений, и в ее записи стек lsFusion указывает на применение (сохранение изменений свойства), а не на оператор присваивания. Само присваивание выполняет - и может записать в лог - только запросы, необходимые для вычисления изменяемых строк и их значений, и запросы к временной таблице сессии, в которую накопленные изменения свойства переносятся из памяти, как только измененных строк становится больше одной |
explainapp | explainAppThresholdexplainThresholdexplainAllocatedBytesThreshold | 1000 мс100 мс0 байт | При включенном для пользователя профилировщике (explainAppEnabled) измеряется каждый вложенный вызов его запроса - время Java, время SQL и, если запрошено, выделенная память, - а выделяющиеся вызовы помечаются в дереве с отступами. Вызов помечается, когда его время Java достигает explainAppThreshold, время SQL - explainThreshold (этот же порог работает и в логе explain, см. параметры работы), а выделенная память превышает explainAllocatedBytesThreshold. Нулевой порог по памяти не помечает каждый вызов, а полностью отключает ее измерение |
explainapp | explainTopAppThresholdexplainTopThresholdexplainTopAllocatedBytesThreshold | 0 мс0 мс0 байт | Будет ли это дерево записано вообще: будет, как только самый внешний вызов запроса достигнет одного из этих значений (порог по памяти проверяется только при включенном ее измерении). При этих значениях по умолчанию самый внешний вызов подходит всегда, поэтому что именно попадет в лог, решают пороги отдельных вызовов выше: запрос, в котором ни один вызов не был помечен, не пишет ничего. Их стоит поднять, чтобы оставить только тяжелые запросы |
sqlhand | explainTemporaryTablesLogSize | 1000 событий | При включенной для соединения трассировке временных таблиц (explainTemporaryTablesEnabled) каждое событие в жизни сессионной таблицы на этом соединении - создание, выдача из пула, очистка, удаление, откат - хранится в памяти, в кольцевом буфере такого размера на соединение. Наружу ничего не пишется, пока это соединение позже не получит ошибку "relation does not exist" по такой таблице: тогда сохраненная история этой таблицы записывается, каждое событие со стеком, который его вызвал |
sqlhand | checkStatementSubstringcheckExcludeStatementSubstring | пусто пусто | Разовый щуп: запрос, в тексте которого, как его формирует драйвер базы данных, встречается первый фрагмент, записывается до выполнения вместе со стеками Java и lsFusion, которые его породили; запрос, в котором встречается и второй фрагмент, пропускается. Задается на время разбирательства и потом очищается |
sqlconflict | logConflictStack | false | Каждый конфликт обновления и взаимоблокировка записываются одной строкой; параметр добавляет к ней стеки Java и lsFusion того запроса, который на них наткнулся, - именно они показывают, какая логика приложения вызвала конфликт |
jdbc | logLevelJDBC | 0 | Направляет сюда внутреннюю трассировку самого драйвера PostgreSQL - уровнем ниже, чем собственный лог sql платформы. Включает ее любое ненулевое значение; это не градация уровня. Применяется при старте и перепроверяется при каждом взятии соединения из пула, поэтому включение доходит до работающего сервера; выключение - нет: драйвер продолжает писать до перезапуска сервера |
exinfo | outSelectLengthThreshold | 100000 символов | Ограничивает текстовый дамп результата запроса, который платформа пишет сюда для отладки: как только выведенные строки его превышают, дамп обрывается и заканчивается and more... |
exinfo | logSqlProcesses | false | Заставляет каждое обновление монитора процессов дополнительно выводить сюда потоки JVM, собственное соответствие сессий базы потокам и каждый опрошенный процесс базы данных - это нужно для отладки того, как монитор сопоставляет процессы потокам, и очень многословно, пока включено |
httpfromexternalsystemrequestshttptoexternalsystemrequests | logFromExternalSystemRequestslogToExternalSystemRequests | falsefalse | Логируют, соответственно, каждый запрос, который внешняя система делает в платформу, и каждый вызов, который платформа делает наружу. Запись содержит метод и адрес запроса, на уровне INFO при успешном ответе и ERROR в противном случае |
httpfromexternalsystemrequestshttptoexternalsystemrequests | logFromExternalSystemRequestsDetaillogToExternalSystemRequestsDetail | falsefalse | Добавляют к этим записям заголовки, куки и тела запроса и ответа; сами по себе, при выключенном параметре выше, они ничего не делают |