├── .github └── workflows │ └── release.yml ├── .gitignore ├── .vscode ├── settings.json └── tasks.json ├── Jenkinsfile ├── README.md ├── doc └── readme.txt ├── lib.config ├── packagedef ├── src ├── basic-layout.os ├── console-appender.os ├── file-appender.os ├── json-layout.os ├── levels.os ├── log-event-builder.os ├── log-event.os ├── log-manager.os ├── log-options.os ├── log.os └── standart-layouts.os ├── tasks ├── coverage.os └── test.os └── tests ├── fixtures ├── appender-debug.os ├── v1-layout.os └── v2-withFields.os ├── json-layout_test.os └── logos-test.os /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Публикация релиза 2 | 3 | on: 4 | release: 5 | types: 6 | - published 7 | workflow_dispatch: 8 | 9 | jobs: 10 | release: 11 | uses: autumn-library/workflows/.github/workflows/release.yml@main 12 | with: 13 | package_mask: "logos-*.ospx" 14 | secrets: 15 | PUSH_TOKEN: ${{ secrets.PUSH_TOKEN }} 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tests.xml 2 | *.ospx 3 | coverage/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "language-1c-bsl.linterEntryPoint": "src/log.os", 4 | "editor.rulers": [ 120 ] 5 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | { 10 | "version": "2.0.0", 11 | "_runner": "terminal", 12 | "windows": { 13 | "command": "cmd", 14 | "args": ["/c", "chcp", "65001", ";"] 15 | }, 16 | "linux": { 17 | "command": "sh", 18 | "args": ["-c"] 19 | }, 20 | "isShellCommand": true, 21 | // "showOutput": "silent", 22 | "tasks": [ 23 | { 24 | "taskName": "Testing project", 25 | "args": [ 26 | "oscript", 27 | "./tasks/test.os" 28 | ], 29 | "echoCommand": true, 30 | "showOutput": "always", 31 | "suppressTaskName": true, 32 | // "isBuildCommand": false, 33 | "isTestCommand": false, 34 | "problemMatcher": { 35 | "fileLocation": "absolute", 36 | "pattern": { 37 | "regexp": "{Модуль\\s+(.+)\\s\\/\\s.*:\\s+(\\d+)\\s+\\/\\s+([^{]*)", 38 | "file": 1, 39 | "location": 2, 40 | "message": 3 41 | } 42 | } 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | 2 | pipeline { 3 | agent none 4 | options { 5 | buildDiscarder(logRotator(numToKeepStr: '7')) 6 | skipDefaultCheckout() 7 | } 8 | 9 | stages { 10 | stage('Тестирование кода пакета WIN') { 11 | 12 | agent { label 'windows' } 13 | 14 | steps { 15 | checkout scm 16 | 17 | script { 18 | if( fileExists ('tasks/test.os') ){ 19 | bat 'chcp 65001 > nul && oscript tasks/test.os' 20 | junit 'junit-*.xml' 21 | } 22 | else 23 | echo 'no testing task' 24 | } 25 | 26 | } 27 | 28 | } 29 | 30 | stage('Тестирование кода пакета LINUX') { 31 | 32 | agent { label 'master' } 33 | 34 | steps { 35 | echo 'under development' 36 | } 37 | 38 | } 39 | 40 | stage('Сборка пакета') { 41 | 42 | agent { label 'windows' } 43 | 44 | steps { 45 | checkout scm 46 | 47 | bat 'erase /Q *.ospx' 48 | bat 'chcp 65001 > nul && call opm build .' 49 | 50 | stash includes: '*.ospx', name: 'package' 51 | archiveArtifacts '*.ospx' 52 | } 53 | 54 | } 55 | 56 | stage('Публикация в хабе') { 57 | when { 58 | branch 'master' 59 | } 60 | agent { label 'master' } 61 | steps { 62 | sh 'rm -f *.ospx' 63 | unstash 'package' 64 | 65 | sh ''' 66 | artifact=`ls -1 *.ospx` 67 | basename=`echo $artifact | sed -r 's/(.+)-.*(.ospx)/\\1/'` 68 | cp $artifact $basename.ospx 69 | sudo rsync -rv *.ospx /var/www/hub.oscript.io/download/$basename/ 70 | '''.stripIndent() 71 | } 72 | } 73 | 74 | stage('Публикация в нестабильном хабе') { 75 | when { 76 | branch 'develop' 77 | } 78 | agent { label 'master' } 79 | steps { 80 | sh 'rm -f *.ospx' 81 | unstash 'package' 82 | 83 | sh ''' 84 | artifact=`ls -1 *.ospx` 85 | basename=`echo $artifact | sed -r 's/(.+)-.*(.ospx)/\\1/'` 86 | cp $artifact $basename.ospx 87 | sudo rsync -rv *.ospx /var/www/hub.oscript.io/dev-channel/$basename/ 88 | '''.stripIndent() 89 | } 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Логирование в стиле log4j 2 | 3 | Библиотека предназначена для удобного вывода сообщений в привязке к их "уровням важности" 4 | 5 | Функционал logos не повторяет полностью log4j, а, скорее, берет из него какие-то аспекты поведения. 6 | 7 | # Использование 8 | 9 | ## Именованные журналы сообщений (Логи) 10 | 11 | Каждый лог имеет собственное имя, по которому он может быть идентифицирован. Имена логов глобально видимы и любой из них может быть получен по имени лога. 12 | 13 | Для того, чтобы начать логирование, требуется вызвать метод `ПолучитьЛог` модуля `Логирование` 14 | 15 | Лог = Логирование.ПолучитьЛог("oscript.app.messages"); 16 | 17 | ### Соглашение об именовании 18 | 19 | Принята следующая схема именования логов: 20 | 21 | область.класс_приложения.имя_лога 22 | 23 | * Область - это произвольное имя, определяющее некую совокупность возможных логов. Часто, в качестве области используется имя поставщика приложения, либо имя набора библиотек. Для всех пакетов, входящих в oscript-library используется имя области "oscript". Приложения, создаваемые, например, в рамках гипотетического проекта "Аврора" могут использовать область "aurora". 24 | * Класс_приложения - это разделитель на тип модуля - библиотека, или приложение. Например, библиотечный пакет "cmdline" использует класс `lib`, а консольное приложение "gitsync" - класс 'app' 25 | * Имя_лога - это, собственно, идентификатор журнала. 26 | 27 | ### Примечание 28 | 29 | В отличие от log4j логи в logos не являются иерархическими, но в перспективе могут стать таковыми. 30 | 31 | ## Уровни логирования 32 | 33 | Существует 5 уровней важности сообщений: 34 | 35 | * Отладка 36 | * Информация 37 | * Предупреждение 38 | * Ошибка 39 | * Критичная ошибка 40 | 41 | Для каждого из уровней logos предоставляет отдельный метод, который выводит сообщение с данным уровнем важности. В процессе эксплуатации приложения для каждого из логов можно устанавливать уровень выводимых сообщений. Например, если установлен уровень "Предупреждение", то выводиться будут только предупреждения или более важные сообщения (Ошибка, КритичнаяОшибка) 42 | 43 | Лог.УстановитьУровень(УровниЛога.Отладка) // выводить все, в т.ч. отладочные сообщения 44 | 45 | По умолчанию установлен уровень "Информация". 46 | 47 | ### Пример использования 48 | 49 | Лог = Логирование.ПолучитьЛог("oscript.test.levels"); 50 | Лог.УстановитьУровень(УровниЛога.Ошибка); 51 | 52 | Лог.Отладка("Переменная А = 7"); 53 | Лог.Информация("Переменная А = 7"); 54 | Лог.Ошибка("Неверно указан путь к файлу!"); 55 | 56 | ПеремА = "А"; 57 | Лог.Отладка("Переменная %1 = %2", ПеремА, 7); 58 | Лог.Информация("Переменная %1 = %2", ПеремА, 7); 59 | Лог.Ошибка("Неверно указан путь к файлу %1!", ПеремА); 60 | 61 | ## Способы вывода (appenders) 62 | 63 | Приложение выводит сообщения в лог, а сам лог может выводиться в произвольное место. За конкретную реализацию вывода отвечает *Способ вывода*. В Log4j это называется appender. 64 | 65 | В составе logos поставляется 2 способа вывода - в консоль и в файл. 66 | Причем, способы вывода - это список, т.е. лог может писаться в несколько мест одновременно. 67 | 68 | ФайлЖурнала = Новый ВыводЛогаВФайл 69 | ФайлЖурнала.ОткрытьФайл("/var/log/oscript.test.log"); 70 | Лог.ДобавитьСпособВывода(ФайлЖурнала); 71 | Лог.Информация("Это строка лога"); 72 | Лог.Закрыть(); // при включении логирования в файл рекомендуется закрывать лог. 73 | 74 | ### Особенности добавления Способов вывода 75 | 76 | При создании лога в него автоматически будет добавлен способ вывода *ВыводЛогаВКонсоль*. Однако, если вручную в лог будет добавлен другой способ вывода, то "автоспособ" будет удален. Иными словами, пример кода выше будет писать только в файл, т.к. консольный вывод при ручном добавлении способа вывода будет отключен. 77 | 78 | ### Особенности формирования логов с дополнительными полями 79 | 80 | В связи с вводом `API v2` для форматирования сообщений, появилась возможность передавать в объект форматирования дополнительные поля. 81 | 82 | Для создания лога с дополнительными полями необходимо использовать следующие функции: 83 | 84 | * `Поля` - принимает на вход поля и значения, где первый параметр имя поля, а второй значение поля и так до 4 полей 85 | 86 | * `ПоляИз` - принимает на соответствие или структуру полей для лога 87 | 88 | > Важно! Надо помнить, что при вызове этих функций создается объект класса `Лог`, вне модуля `Логирование`. И он не меняет `Лог` с таким же именем и живет только внутри вызванных методов 89 | 90 | Пример использования: 91 | 92 | ```bsl 93 | ЛогБиблиотеки = Логирование.ПолучитьЛог("oscript.lib.test"); 94 | 95 | ПоляЛога = Новый Структура("ДопПоле, ДопПоле2", "ДопПоле", "ДопПоле2"); 96 | 97 | Лог = ЛогБиблиотеки.ПоляИз(ПоляЛога); 98 | 99 | Лог.Отладка("Это отладка"); 100 | 101 | // ИЛИ 102 | 103 | ЛогБиблиотеки.Поля("ДатаВремя", ТекущаяДата(), "ПростоПоле", "ПростоПоле").Информация("Привет"); 104 | 105 | ``` 106 | 107 | 108 | ## Форматирование сообщений 109 | 110 | За форматирование выводимых сообщений отвечает *Раскладка*. Раскладка по умолчанию форматирует сообщения следующим образом: 111 | 112 | УРОВЕНЬСООБЩЕНИЯ - ТекстСообщения 113 | 114 | Раскладка - это класс, реализующий метод *Форматировать(Знач Уровень, Знач Сообщение)*. Установить собственную раскладку можно методом "УстановитьРаскладку". 115 | 116 | * API v1 117 | ```bsl 118 | Функция Форматировать(Знач Уровень, Знач Сообщение) Экспорт 119 | 120 | Возврат СтрШаблон("%1: %2 - %3", ТекущаяДата(), УровниЛога.НаименованиеУровня(Уровень), Сообщение); 121 | 122 | КонецФункции 123 | ``` 124 | * API v2 125 | ```bsl 126 | Функция ПолучитьФорматированноеСообщение(Знач СобытиеЛога) Экспорт 127 | 128 | // СобытиеЛога - Объект с методами 129 | // * ПолучитьУровень() - Число - уровень лога 130 | // * ПолучитьСообщение() - Строка - текст сообщения 131 | // * ПолучитьИмяЛога() - Строка - имя лога 132 | // * ПолучитьВремяСобытия() - Число - Универсальная дата-время события в миллисекундах 133 | // * ПолучитьДополнительныеПоля() - Соответствие - дополнительные поля события 134 | 135 | ФорматированноеСообщение = СобытиеЛога.ПолучитьСообщение(); 136 | 137 | Возврат ФорматированноеСообщение; 138 | 139 | КонецФункции 140 | ``` 141 | ```bsl 142 | Лог = Логирование.ПолучитьЛог("oscript.lib.test"); 143 | Лог.УстановитьРаскладку(ЭтотОбъект); 144 | ``` 145 | 146 | В приведенной раскладке в сообщение помимо уровня и текста будет добавлено текущая дата. 147 | 148 | # Конфигурирование логов 149 | 150 | Предусмотрено изменение параметров логирования через специальный файл конфигурации, либо через переменную окружения. 151 | Независимо от способа задания настроек, формат настроек остается одинаковым. 152 | 153 | Файл конфигурации должен лежать рядом со стартовым скриптом (см. метод *СтартовыйСценарий()*) и называться *logos.cfg*. Кроме того, настройки можно задать через переменную окружения LOGOS_CONFIG. Из-за неудобства ввода перевода строк в переменных окружения - в данном случае настройки надо разделять не переводом строк, а точкой-с-запятой. Формат настроек идентичен, независимо от способа задания конфига - в файле или в переменной. 154 | 155 | Следует учитывать, что переменная окружения имеет приоритет над файлом, и если задана она, то настройки берутся из нее, файл игнорируется. 156 | 157 | ### Пример задания настроек через командную строку: 158 | ```cmd 159 | set LOGOS_CONFIG=logger.oscript.lib.commands=DEBUG;logger.oscript.lib.cmdline=DEBUG 160 | ``` 161 | 162 | ## Иерархия наследования настроек логов 163 | Если задать настройку: 164 | ```cmd 165 | set LOGOS_CONFIG=logger.oscript.lib.query=DEBUG; 166 | ``` 167 | И получить вот такие логи: 168 | ``` 169 | ЛогОбновления = Логирование.ПолучитьЛог("oscript.lib.query.update"); 170 | ЛогВыборки = Логирование.ПолучитьЛог("oscript.lib.query.select"); 171 | ``` 172 | То оба лога унаследуют настройки ```oscript.lib.query``` 173 | 174 | ## Формат настроек логирования 175 | 176 | Каждая настройка задается в виде пары ```ключ=значение```. Причем, ключ является составным. Компоненты ключа разделены точками. 177 | Первым компонентом ключа идет *класс настройки*. Предусмотрены 2 класса - *logger* и *appender*. Первый отвечает за настройку конкретного журнала. Второй - за настройку способов вывода, используемых журналами. 178 | 179 | ### Настройка журнала (класс logger) 180 | 181 | logger.имя_журнала=Уровень[,СпособыВывода] 182 | 183 | * имя_журнала - это имя лога, как он описан в вызове метода ```Логирование.ПолучитьЛог();```, например, **oscript.lib.v8runner**. 184 | * СпособыВывода - это список произвольных имен способов вывода, которые привязаны к журналу. Конкретная настройка каждого из заявленных способов вывода выполняется в классе настроек *appender*. 185 | 186 | Например, журнал **oscript.lib.v8runner** может быть настроен следующим образом: 187 | 188 | logger.oscript.lib.v8runner=DEBUG, v8rdebug, console 189 | 190 | ### Корневой журнал (логгер) 191 | 192 | В классе настроек logger возможно указать специализированное имя ``rootLogger``. Настройки корневого логгера влияют на все прочие журналы. Это удобно, если вы хотите просто включить отладку по всем журналам или все журналы направить в файл. 193 | 194 | Например: 195 | 196 | logger.rootLogger=DEBUG 197 | 198 | ### Настройка через переменные среды 199 | 200 | Обычная установка через командную строку, например, используя отдельный командный файл 201 | 202 | set LOGOS_CONFIG=logger.rootLogger=DEBUG 203 | 204 | 205 | или 206 | 207 | set LOGOS_LEVEL=DEBUG 208 | 209 | Установка и немедленный запуск команды-скрипта через командную строку без создания командного файла 210 | 211 | (LOGOS_LEVEL=DEBUG) && (любая команда) 212 | 213 | или 214 | 215 | (set LOGOS_CONFIG=logger.rootLogger=DEBUG) && (любая команда) 216 | 217 | Например: 218 | 219 | (LOGOS_LEVEL=DEBUG) && (vanessa-runner help) 220 | 221 | или 222 | 223 | (set LOGOS_CONFIG=logger.rootLogger=DEBUG) && (vanessa-runner help) 224 | 225 | ### Настройка способа вывода (класс appender) 226 | 227 | logger.oscript.lib.v8runner=DEBUG, v8rdebug, console 228 | appender.v8rdebug=ВыводЛогаВФайл 229 | appender.v8rdebug.level=DEBUG 230 | appender.v8rdebug.file=/var/log/v8runner-debug.log 231 | 232 | appender.console=ВыводЛогаВКонсоль 233 | appender.console.level=INFO 234 | 235 | В приведенном примере для лога oscript.lib.v8runner установлен уровень Отладка и заявлено 2 способа вывода. Они названы v8rdebug и console (названия произвольные, т.е. здесь мы "объявляем" эти названия, придумав их самостоятельно, а ниже - по ним обращаемся к настройке логгера). 236 | 237 | Далее, в конфигурации указаны настройки заявленных способов вывода (аппендеров). Обязательным параметром является класс (тип языка), реализующий способ вывода. В данном примере указаны типы **ВыводЛогаВФайл** и **ВыводЛогаВКонсоль**. 238 | 239 | // формат указания класса реализации 240 | appender.имя_способа_вывода=Класс 241 | 242 | Для каждого класса можно установить собственный уровень вывода сообщений. В этом случае перед выводом сообщения система логирования будет фильтровать сообщения. 243 | Для установки нужно заполнить свойство `level`. Возможные значения для свойства - `DEFAULT`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `CRITICALERROR`, `DISABLE` 244 | 245 | Например, в указанном выше примере для способа вывода `console` (который мы сами так назвали выше) установлен уровень вывода сообщений информации и более серьезных. Отладочные сообщения в эту консоль не выводятся. 246 | А вот для способа вывода `v8rdebug` (который мы тоже сами так назвали выше) установлен уровень вывода сообщений `Отладка`. Т.е. этим способом вывода будут выводиться все сообщения! 247 | 248 | appender.v8rdebug.level=DEBUG 249 | appender.console.level=INFO 250 | 251 | Для каждого класса могут потребоваться какие-то свои параметры. Например, класс ВыводЛогаВФайл требует задания свойства file. Свойства способа вывода задаются через точку от имени способа вывода: 252 | 253 | // формат указания свойства 254 | appender.имя_способа_вывода.свойство=значение 255 | 256 | ## Примеры настройки 257 | 258 | ## Я хочу включить отладочный лог приложения 259 | 260 | Для этого нужно включить уровень логирования DEBUG для всех логгеров приложения 261 | 262 | ### С помощью файла logos.cfg 263 | 264 | logger.rootLogger=DEBUG 265 | 266 | ### С помощью переменной окружения LOGOS_CONFIG 267 | 268 | set LOGOS_CONFIG=logger.rootLogger=DEBUG 269 | 270 | Обратите внимание, значение переменной LOGOS_CONFIG это **то же самое, что** строки файла logos.cfg. Строки отделяются друг-от-друга точкой с запятой. 271 | 272 | ### С помощью переменной окружения LOGOS_LEVEL 273 | 274 | Переменная LOGOS_LEVEL является сокращенным способом доступа к настройке logger.rootLogger, для удобства 275 | 276 | set LOGOS_LEVEL=DEBUG 277 | 278 | ## Я хочу выводить лог некоторой библиотеки connector в файл http.log 279 | 280 | Дано: приложение SOME_APP, которое общается по сети с помощью библиотеки connector. 281 | Пусть: известно, что библиотека connector пишет в лог с именем `oscript.lib.connector` 282 | 283 | ### С помощью файла logos.cfg 284 | 285 | ``` 286 | logger.oscript.lib.connector=INFO, foo 287 | appender.foo=ВыводЛогаВФайл 288 | appender.foo.file=/var/log/http.log 289 | ``` 290 | 291 | Обратите внимание, в первой строке объявлено, что логгер oscript.lib.connector связан с аппендером foo (название придумали сами, прямо тут). Далее, во второй строке указывается, что аппендер foo (который мы придумали) является классом `ВыводЛогаВФайл` и пишет в файл /var/log/http.log 292 | 293 | ### С помощью переменной окружения LOGOS_CONFIG 294 | 295 | При использовании переменной окружения мы должны просто повторить строки файла конфигурации, разделив их точкой-с-запятой. 296 | 297 | set LOGOS_CONFIG=logger.oscript.lib.connector=INFO, foo;appender.foo=ВыводЛогаВФайл;appender.foo.file=/var/log/http.log 298 | 299 | Таким образом, если у нас есть приложение, настройки логирования которого надо переопределить, мы должны создать рядом со стартовым скриптом приложения файл logos.cfg, либо (если не знаем где лежит этот файл или нет к нему доступа) создать переменную окружения LOGOS_CONFIG, написав в ней строки конфигурирования, разделив их точкой-с-запятой. 300 | -------------------------------------------------------------------------------- /doc/readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscript-library/logos/9e46fe0cb5d505cb49fe7d17f0472e522fea1d5c/doc/readme.txt -------------------------------------------------------------------------------- /lib.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packagedef: -------------------------------------------------------------------------------- 1 |  2 | Описание.Имя("logos") 3 | .Версия("1.7.1") 4 | .ЗависитОт("asserts", "0.4.0") 5 | .ВключитьФайл("src") 6 | .ВключитьФайл("tests") 7 | .ВключитьФайл("lib.config") 8 | .ВерсияСреды("1.9.2") 9 | ; 10 | // vim: filetype=onescript 11 | -------------------------------------------------------------------------------- /src/basic-layout.os: -------------------------------------------------------------------------------- 1 | Функция ПолучитьФорматированноеСообщение(Знач СобытиеЛога) Экспорт 2 | 3 | УровеньЛога = СобытиеЛога.ПолучитьУровеньЛога(); 4 | УровеньСообщения = СобытиеЛога.ПолучитьУровень(); 5 | НаименованиеУровня = УровниЛога.НаименованиеУровня(УровеньСообщения); 6 | Сообщение = СобытиеЛога.ПолучитьСообщение(); 7 | ИмяЛога = СобытиеЛога.ПолучитьИмяЛога(); 8 | 9 | Если УровеньЛога <= УровниЛога.Отладка Тогда 10 | ФорматированноеИмяЛога = ФорматироватьИмяЛога(ИмяЛога); 11 | ФорматированноеСообщение = СтрШаблон("%1 - [%2] - %3", НаименованиеУровня, ФорматированноеИмяЛога, Сообщение); 12 | Иначе 13 | ФорматированноеСообщение = СтрШаблон("%1 - %2", НаименованиеУровня, Сообщение); 14 | КонецЕсли; 15 | СтрокаПолей = ФорматироватьДополнительныеПоля(СобытиеЛога.ПолучитьДополнительныеПоля()); 16 | Если Не ПустаяСтрока(СтрокаПолей) Тогда 17 | ФорматированноеСообщение = ФорматированноеСообщение + " " + СтрокаПолей; 18 | КонецЕсли; 19 | 20 | Возврат ФорматированноеСообщение; 21 | 22 | КонецФункции 23 | 24 | Функция ФорматироватьДополнительныеПоля(Знач ДополнительныеПоля) 25 | 26 | МассивСтрокПолей = Новый Массив(); 27 | Для каждого Поле Из ДополнительныеПоля Цикл 28 | СтрокаПоля = СтрШаблон("%1=%2", Поле.Ключ, Поле.Значение); 29 | МассивСтрокПолей.Добавить(СтрокаПоля); 30 | КонецЦикла; 31 | 32 | Возврат СтрСоединить(МассивСтрокПолей, " "); 33 | 34 | КонецФункции 35 | 36 | Функция ФорматироватьИмяЛога(Знач ИмяЛога) 37 | 38 | КоличествоСимволов = 20; 39 | Результат = ""; 40 | 41 | ИтоговаяДлинаЛога = СтрДлина(ИмяЛога); 42 | Если ИтоговаяДлинаЛога <= КоличествоСимволов Тогда 43 | Возврат ИмяЛога; 44 | КонецЕсли; 45 | 46 | УзлыЛога = СтрРазделить(ИмяЛога, "."); 47 | 48 | Если УзлыЛога.Количество() = 1 Тогда 49 | Результат = СократитьСтроку(ИмяЛога, КоличествоСимволов); 50 | Возврат Результат; 51 | КонецЕсли; 52 | 53 | НеобходимоСокращатьУзелЛога = Истина; 54 | сч = 0; 55 | Для Каждого УзелЛога Из УзлыЛога Цикл 56 | 57 | ПоследнийУзелЛога = сч = УзлыЛога.ВГраница(); 58 | 59 | Если НеобходимоСокращатьУзелЛога Тогда 60 | Если ПоследнийУзелЛога Тогда 61 | РезультирующийУзелЛога = СократитьСтроку(УзелЛога, Макс(1, КоличествоСимволов - СтрДлина(Результат))); 62 | Иначе 63 | РезультирующийУзелЛога = Лев(УзелЛога, 1); 64 | КонецЕсли; 65 | Иначе 66 | РезультирующийУзелЛога = УзелЛога; 67 | КонецЕсли; 68 | 69 | Результат = Результат + РезультирующийУзелЛога + "."; 70 | ИтоговаяДлинаЛога = ИтоговаяДлинаЛога - (СтрДлина(УзелЛога) - 1); 71 | 72 | Если ИтоговаяДлинаЛога <= КоличествоСимволов Тогда 73 | НеобходимоСокращатьУзелЛога = Ложь; 74 | КонецЕсли; 75 | 76 | сч = сч + 1; 77 | КонецЦикла; 78 | 79 | Результат = Лев(Результат, СтрДлина(Результат) - 1); 80 | 81 | Возврат Результат; 82 | 83 | КонецФункции 84 | 85 | Функция СократитьСтроку(Знач ИсходнаяСтрока, Знач КоличествоСимволов) 86 | 87 | Результат = ИсходнаяСтрока; 88 | 89 | Если СтрДлина(Результат) <= КоличествоСимволов Тогда 90 | Возврат Результат; 91 | КонецЕсли; 92 | 93 | Результат = "~" + Прав(Результат, Макс(КоличествоСимволов - 1, 1)); 94 | 95 | Возврат Результат; 96 | 97 | КонецФункции 98 | -------------------------------------------------------------------------------- /src/console-appender.os: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // LOGOS: вывод в консоль 4 | // 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | Перем КартаСтатусовИУровней; 8 | 9 | Процедура ВывестиСобытие(Знач СобытиеЛога) Экспорт 10 | Сообщение = СобытиеЛога.ПолучитьФорматированноеСообщение(); 11 | УровеньСообщения = СобытиеЛога.ПолучитьУровень(); 12 | 13 | Сообщить(Сообщение, КартаСтатусовИУровней[УровеньСообщения]); 14 | КонецПроцедуры 15 | 16 | Процедура Закрыть() Экспорт 17 | 18 | КонецПроцедуры 19 | 20 | // Устанавливает свойство аппендера, заданное в конфигурационном файле 21 | // 22 | Процедура УстановитьСвойство(Знач ИмяСвойства, Знач Значение) Экспорт 23 | 24 | КонецПроцедуры // УстановитьСвойство() 25 | 26 | КартаСтатусовИУровней = Новый Соответствие; 27 | КартаСтатусовИУровней.Вставить(УровниЛога.Отладка, СтатусСообщения.БезСтатуса); 28 | КартаСтатусовИУровней.Вставить(УровниЛога.Информация, СтатусСообщения.Обычное); 29 | КартаСтатусовИУровней.Вставить(УровниЛога.Предупреждение, СтатусСообщения.Внимание); 30 | КартаСтатусовИУровней.Вставить(УровниЛога.Ошибка, СтатусСообщения.Важное); 31 | КартаСтатусовИУровней.Вставить(УровниЛога.КритичнаяОшибка, СтатусСообщения.ОченьВажное); -------------------------------------------------------------------------------- /src/file-appender.os: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // LOGOS: вывод в файл 4 | // 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | Перем ФайлЛога; 8 | 9 | Процедура ОткрытьФайл(Знач Путь, Знач Кодировка = "utf-8", Знач Добавлять = Истина) Экспорт 10 | ФайлЛога = Новый ЗаписьТекста(Путь, Кодировка,,Добавлять); 11 | КонецПроцедуры 12 | 13 | Процедура Вывести(Знач Сообщение, Знач УровеньСообщения) Экспорт 14 | ПроверитьИнициализацию(); 15 | ФайлЛога.ЗаписатьСтроку(Сообщение); 16 | КонецПроцедуры 17 | 18 | Процедура Закрыть() Экспорт 19 | Если НЕ ФайлЛога = Неопределено Тогда 20 | ФайлЛога.Закрыть(); 21 | ФайлЛога = Неопределено; 22 | КонецЕсли; 23 | КонецПроцедуры 24 | 25 | // Устанавливает свойство аппендера, заданное в конфигурационном файле 26 | // 27 | Процедура УстановитьСвойство(Знач ИмяСвойства, Знач Значение) Экспорт 28 | Если ИмяСвойства = "file" Тогда 29 | ОткрытьФайл(Значение); 30 | КонецЕсли; 31 | КонецПроцедуры // УстановитьСвойство() 32 | 33 | Процедура ПроверитьИнициализацию() 34 | Если ФайлЛога = Неопределено Тогда 35 | ВызватьИсключение "Не открыт файл лога"; 36 | КонецЕсли; 37 | КонецПроцедуры 38 | -------------------------------------------------------------------------------- /src/json-layout.os: -------------------------------------------------------------------------------- 1 | Перем ФорматДатыСобытия; 2 | Перем КартаУровней; 3 | Перем ПараметрыЗаписиJSON; 4 | 5 | Функция ПолучитьФорматированноеСообщение(Знач СобытиеЛога) Экспорт 6 | 7 | // СобытиеЛога - Объект с методами 8 | // * ПолучитьУровень() - Число - уровень лога 9 | // * ПолучитьСообщение() - Строка - текст сообщения 10 | // * ПолучитьИмяЛога() - Строка - имя лога 11 | // * ПолучитьВремяСобытия() - Число - Универсальная дата-время события в миллисекундах 12 | // * ПолучитьДополнительныеПоля() - Соответствие - дополнительные поля события 13 | 14 | Сообщение = СобытиеЛога.ПолучитьСообщение(); 15 | УровеньСообщения = СобытиеЛога.ПолучитьУровень(); 16 | УровеньЛога = СобытиеЛога.ПолучитьУровеньЛога(); 17 | ДатаСобытия = СобытиеЛога.ПолучитьВремяСобытия(); 18 | ДопПоля = СобытиеЛога.ПолучитьДополнительныеПоля(); 19 | ИмяЛога = СобытиеЛога.ПолучитьИмяЛога(); 20 | 21 | ФорматированноеСообщение = СформироватьФорматированныеСообщение(ДатаСобытия, УровеньСообщения, 22 | УровеньЛога, Сообщение, 23 | ДопПоля, ИмяЛога); 24 | 25 | Возврат ФорматированноеСообщение; 26 | 27 | КонецФункции 28 | 29 | Функция СформироватьФорматированныеСообщение(Знач ДатаСобытияВМиллисекундах, Знач УровеньСообщения, Знач УровеньЛога, Знач Сообщение, Знач ДопПоля, Знач ИмяЛога) 30 | 31 | СтруктураДаты = РазложитьДатуВМиллисекундах(ДатаСобытияВМиллисекундах); 32 | 33 | ФорматированнаяДатаСобытия = ФорматироватьДатуСобытия(СтруктураДаты.Дата, СтруктураДаты.Миллисекунды); 34 | 35 | СтруктураЛога = Новый Соответствие(); 36 | СтруктураЛога.Вставить("time", ФорматированнаяДатаСобытия); 37 | СтруктураЛога.Вставить("level", ФорматироватьУровеньСообщения(УровеньСообщения)); 38 | СтруктураЛога.Вставить("msg", Сообщение); 39 | СтруктураЛога.Вставить("log", ИмяЛога); 40 | 41 | Для каждого ПолеЛога Из ДопПоля Цикл 42 | Значение = ПолеЛога.Значение; 43 | ТипЗначения =ТипЗнч(Значение); 44 | Если ТипЗначения = Тип("Строка") 45 | ИЛИ ТипЗначения = Тип("Число") 46 | ИЛИ ТипЗначения = Тип("Дата") 47 | ИЛИ ТипЗначения = Тип("Булево") Тогда 48 | // Все хорошо эти типы сериализуются 49 | ИначеЕсли ТипЗнч(Значение) = Тип("ИнформацияОбОшибке") Тогда 50 | 51 | Если УровеньЛога = УровниЛога.Отладка Тогда 52 | 53 | СтруктураЛога.Вставить(СтрШаблон("%1.%2", ПолеЛога.Ключ, "ИмяМодуля"), Значение.ИмяМодуля); 54 | СтруктураЛога.Вставить(СтрШаблон("%1.%2", ПолеЛога.Ключ, "НомерСтроки"), Значение.НомерСтроки); 55 | 56 | Если ЗначениеЗаполнено(Значение.Параметры) Тогда 57 | СтруктураЛога.Вставить(СтрШаблон("%1.%2", ПолеЛога.Ключ, "Параметры"), Значение.Параметры); 58 | КонецЕсли; 59 | 60 | КонецЕсли; 61 | 62 | Значение = Значение.Описание; 63 | 64 | Иначе 65 | 66 | Значение = Строка(Значение); 67 | 68 | КонецЕсли; 69 | 70 | СтруктураЛога.Вставить(ПолеЛога.Ключ, Значение); 71 | 72 | КонецЦикла; 73 | 74 | ЗаписьJSON = Новый ЗаписьJSON(); 75 | ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписиJSON); 76 | 77 | ЗаписатьJSON(ЗаписьJSON, СтруктураЛога); 78 | 79 | Возврат ЗаписьJSON.Закрыть(); 80 | 81 | КонецФункции 82 | 83 | Функция РазложитьДатуВМиллисекундах(УниверсальнаяДатаВМиллисекундах) 84 | 85 | ПолныеМиллисекунды = Окр(УниверсальнаяДатаВМиллисекундах, 0); 86 | 87 | ОкругленныеМС = Окр(ПолныеМиллисекунды/1000, 0, 0) * 1000; 88 | Миллисекунды = ПолныеМиллисекунды - ОкругленныеМС; 89 | 90 | Если Миллисекунды < 0 Тогда 91 | Миллисекунды = 1000 + Миллисекунды; 92 | КонецЕсли; 93 | 94 | Секунды = (ПолныеМиллисекунды - Миллисекунды)/1000; 95 | 96 | ТиповаяДата = Дата("00010101") + Секунды; 97 | 98 | Возврат Новый Структура("Дата, Секунды, Миллисекунды", ТиповаяДата, Секунды, Миллисекунды); 99 | 100 | КонецФункции 101 | 102 | // Устанавливает произвольный формат вывода даты 103 | // 104 | // Параметры: 105 | // ФорматДаты - Строка - строковое представление формата для вывода даты 106 | // 107 | Процедура УстановитьФорматДатыСобытия(Знач ФорматДаты) 108 | ФорматДатыСобытия = СтрШаблон("ДФ='%1'", ФорматДаты); 109 | КонецПроцедуры 110 | 111 | Функция ФорматироватьДатуСобытия(Знач ДатаСобытия, Знач МилисекундыСобытия) 112 | Возврат СтрШаблон(Формат(ДатаСобытия, ФорматДатыСобытия), Формат(МилисекундыСобытия, "ЧЦ=3; ЧВН=")); 113 | КонецФункции 114 | 115 | Функция ФорматироватьУровеньСообщения(Знач УровеньСообщения) 116 | 117 | СтрокаУровня = КартаУровней[УровеньСообщения]; 118 | 119 | Если СтрокаУровня = Неопределено Тогда 120 | СтрокаУровня = КартаУровней[0]; 121 | КонецЕсли; 122 | 123 | Возврат СтрокаУровня; 124 | 125 | КонецФункции 126 | 127 | Функция КартаУровнейПоУмолчанию() 128 | 129 | КартаСтатусовИУровней = Новый Соответствие; 130 | КартаСтатусовИУровней.Вставить(УровниЛога.Отладка, "DEBUG");// ОТЛАДКА 131 | КартаСтатусовИУровней.Вставить(УровниЛога.Информация, "INFO");// ИНФО 132 | КартаСтатусовИУровней.Вставить(УровниЛога.Предупреждение, "WARN");// ВНИМАНИЕ 133 | КартаСтатусовИУровней.Вставить(УровниЛога.Ошибка, "ERROR");// ОШИБКА 134 | КартаСтатусовИУровней.Вставить(УровниЛога.КритичнаяОшибка, "FATAL");// КРИТИЧНА 135 | 136 | Возврат КартаСтатусовИУровней; 137 | 138 | КонецФункции 139 | 140 | Процедура ПриСозданииОбъекта() 141 | 142 | УстановитьФорматДатыСобытия("yyyy-MM-ddTHH:mm:ss.%1Z"); 143 | КартаУровней = КартаУровнейПоУмолчанию(); 144 | 145 | ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON( 146 | ПереносСтрокJSON.Нет, // Способ переноса строк 147 | "", // Символ отступа 148 | Истина, // Использовать двойные кавычки 149 | ЭкранированиеСимволовJSON.Нет, // Способ экранирования символов 150 | Ложь, // Экранировать угловые скобки `<` и `>` 151 | Истина, // Экранировать переносы строк 152 | Ложь, // Экранировать амперсанд `&` 153 | Истина, // Экранировать одинарные кавычки `'` 154 | Истина // Экранировать слеш `\` 155 | ); 156 | 157 | КонецПроцедуры -------------------------------------------------------------------------------- /src/levels.os: -------------------------------------------------------------------------------- 1 |  2 | Перем мУровниПриоритета; 3 | Перем мНаименованиеУровней; 4 | 5 | Перем Отладка Экспорт; 6 | Перем Информация Экспорт; 7 | Перем Предупреждение Экспорт; 8 | Перем Ошибка Экспорт; 9 | Перем КритичнаяОшибка Экспорт; 10 | Перем Отключить Экспорт; 11 | 12 | ////////////////////////////////////////////////////////////////////////////////// 13 | 14 | Функция НаименованиеУровня(Знач Уровень) Экспорт 15 | Возврат мНаименованиеУровней[Уровень]; 16 | КонецФункции 17 | 18 | // Вернуть все возможнные уровни 19 | // 20 | // Возвращаемое значение: 21 | // ФиксированнаяСтруктура - результат 22 | // * Ключ - Строка - имя уровня, Отладка, Информация и т.п. 23 | // * Ключ - Число - показатель уровня. У Отладка 0 (мин), у Отключить 5 (макс) 24 | // 25 | Функция Уровни() Экспорт 26 | Возврат Новый ФиксированнаяСтруктура(мУровниПриоритета); 27 | КонецФункции 28 | 29 | ////////////////////////////////////////////////////////////////////////////////// 30 | // СЛУЖЕБНЫЕ ПРОЦЕДУРЫ 31 | // 32 | 33 | Процедура Инициализация() 34 | 35 | ИнициализироватьУровни(); 36 | ИнициализироватьНаименованияУровней(); 37 | 38 | КонецПроцедуры 39 | 40 | Процедура ИнициализироватьУровни() 41 | 42 | мУровниПриоритета = Новый Структура; 43 | мУровниПриоритета.Вставить("Отладка" , 0); 44 | мУровниПриоритета.Вставить("Информация" , 1); 45 | мУровниПриоритета.Вставить("Предупреждение" , 2); 46 | мУровниПриоритета.Вставить("Ошибка" , 3); 47 | мУровниПриоритета.Вставить("КритичнаяОшибка", 4); 48 | мУровниПриоритета.Вставить("Отключить" , 5); 49 | 50 | Для Каждого КлючИЗначение Из мУровниПриоритета Цикл 51 | ЭтотОбъект[КлючИЗначение.Ключ] = КлючИЗначение.Значение; 52 | КонецЦикла; 53 | 54 | КонецПроцедуры 55 | 56 | Процедура ИнициализироватьНаименованияУровней() 57 | 58 | мНаименованиеУровней = Новый Соответствие; 59 | мНаименованиеУровней.Вставить(мУровниПриоритета.Отладка , "ОТЛАДКА"); 60 | мНаименованиеУровней.Вставить(мУровниПриоритета.Информация , "ИНФОРМАЦИЯ"); 61 | мНаименованиеУровней.Вставить(мУровниПриоритета.Предупреждение , "ПРЕДУПРЕЖДЕНИЕ"); 62 | мНаименованиеУровней.Вставить(мУровниПриоритета.Ошибка , "ОШИБКА"); 63 | мНаименованиеУровней.Вставить(мУровниПриоритета.КритичнаяОшибка, "КРИТИЧНАЯОШИБКА"); 64 | мНаименованиеУровней.Вставить(мУровниПриоритета.Отключить , "ОТКЛЮЧИТЬ"); 65 | 66 | КонецПроцедуры 67 | 68 | Инициализация(); 69 | -------------------------------------------------------------------------------- /src/log-event-builder.os: -------------------------------------------------------------------------------- 1 | Перем Уровень; 2 | Перем Сообщение; 3 | Перем ИмяЛога; 4 | Перем ВремяСобытия; 5 | Перем УровеньЛога; 6 | Перем ДополнительныеПоля; 7 | 8 | // Конструирует событие лога по данным строителя 9 | // 10 | // Возвращаемое значение: 11 | // СобытиеЛога - Настроенный объект СобытиеЛога 12 | // 13 | Функция Создать() Экспорт 14 | СобытиеЛога = Новый СобытиеЛога(ИмяЛога, Уровень, Сообщение, ВремяСобытия, УровеньЛога, ДополнительныеПоля); 15 | Возврат СобытиеЛога; 16 | КонецФункции 17 | 18 | // Устанавливает имя лога 19 | // 20 | // Параметры: 21 | // ПИмяЛога - Строка - Имя лога 22 | // 23 | Процедура УстановитьИмяЛога(Знач ПИмяЛога) Экспорт 24 | ИмяЛога = ПИмяЛога; 25 | КонецПроцедуры 26 | 27 | // Устанавливает уровень сообщения 28 | // 29 | // Параметры: 30 | // ПУровень - Уровень - Уровень лога 31 | // 32 | Процедура УстановитьУровень(Знач ПУровень) Экспорт 33 | Уровень = ПУровень; 34 | КонецПроцедуры 35 | 36 | // Устанавливает уровень лога 37 | // 38 | // Параметры: 39 | // ПУровень - Уровень - Уровень лога 40 | // 41 | Процедура УстановитьУровеньЛога(Знач ПУровеньЛога) Экспорт 42 | УровеньЛога = ПУровеньЛога; 43 | КонецПроцедуры 44 | 45 | // Устанавливает текст сообщения 46 | // 47 | // Параметры: 48 | // ПСообщение - Строка - Текст сообщения 49 | // 50 | Процедура УстановитьСообщение(Знач ПСообщение) Экспорт 51 | Сообщение = ПСообщение; 52 | КонецПроцедуры 53 | 54 | // Устанавливает дату-время события 55 | // 56 | // Параметры: 57 | // ПВремяСобытия - Число - Универсальная дата-время события в миллисекундах 58 | // 59 | Процедура УстановитьВремяСобытия(Знач ПВремяСобытия) Экспорт 60 | ВремяСобытия = ПВремяСобытия; 61 | КонецПроцедуры 62 | 63 | // Устанавливает дополнительные поля события 64 | // 65 | // Параметры: 66 | // ПДополнительныеПоля - Соответствие, Структура - данные с дополнительными полями события 67 | // 68 | Процедура УстановитьДополнительныеПоля(Знач ПДополнительныеПоля) Экспорт 69 | ДополнительныеПоля = ПДополнительныеПоля; 70 | КонецПроцедуры 71 | -------------------------------------------------------------------------------- /src/log-event.os: -------------------------------------------------------------------------------- 1 | Перем Уровень; 2 | Перем Сообщение; 3 | Перем ФорматированноеСообщение; 4 | Перем ИмяЛога; 5 | Перем ВремяСобытия; 6 | Перем УровеньЛога; 7 | Перем ДополнительныеПоля; 8 | 9 | Процедура ПриСозданииОбъекта(ПИмяЛога = "", ПУровень = "", 10 | ПСообщение = "", ПВремяСобытия = 0, 11 | ПУровеньЛога = 0, ПДополнительныеПоля = Неопределено) 12 | 13 | Уровень = ПУровень; 14 | УровеньЛога = ПУровеньЛога; 15 | Сообщение = ПСообщение; 16 | ИмяЛога = ПИмяЛога; 17 | ВремяСобытия = ПВремяСобытия; 18 | ДополнительныеПоля = ПДополнительныеПоля; 19 | ФорматированноеСообщение = ""; 20 | 21 | КонецПроцедуры 22 | 23 | // Получить уровень сообщения 24 | // 25 | // Возвращаемое значение: 26 | // УровниЛога.НаименованиеУровня - Уровень лога, установленный при формировании сообщения 27 | // 28 | Функция ПолучитьУровень() Экспорт 29 | Возврат Уровень; 30 | КонецФункции 31 | 32 | // Получить уровень лога 33 | // 34 | // Возвращаемое значение: 35 | // УровниЛога.НаименованиеУровня - Уровень лога, установленный при формировании сообщения 36 | // 37 | Функция ПолучитьУровеньЛога() Экспорт 38 | Возврат УровеньЛога; 39 | КонецФункции 40 | 41 | // Получить текст сообщения 42 | // 43 | // Возвращаемое значение: 44 | // Строка - Текст сообщения 45 | // 46 | Функция ПолучитьСообщение() Экспорт 47 | Возврат Сообщение; 48 | КонецФункции 49 | 50 | // Получить форматированный текст сообщения 51 | // 52 | // Возвращаемое значение: 53 | // Строка - Форматированный текст сообщения 54 | // 55 | Функция ПолучитьФорматированноеСообщение() Экспорт 56 | Возврат ФорматированноеСообщение; 57 | КонецФункции 58 | 59 | // Получить имя лога 60 | // 61 | // Возвращаемое значение: 62 | // Строка - Имя лога 63 | // 64 | Функция ПолучитьИмяЛога() Экспорт 65 | Возврат ИмяЛога; 66 | КонецФункции 67 | 68 | // Получить дату-время события 69 | // 70 | // Возвращаемое значение: 71 | // Число - Универсальная дата-время события в миллисекундах 72 | // 73 | Функция ПолучитьВремяСобытия() Экспорт 74 | Возврат ВремяСобытия; 75 | КонецФункции 76 | 77 | // Получить дополнительные поля события 78 | // 79 | // Возвращаемое значение: 80 | // Соответствие - дополнительные поля события 81 | // 82 | Функция ПолучитьДополнительныеПоля() Экспорт 83 | Возврат ДополнительныеПоля; 84 | КонецФункции 85 | 86 | // Устанавливает текст отформатированного сообщения 87 | // 88 | // Параметры: 89 | // ПФорматированноеСообщение - Строка - Текст отформатированного сообщения 90 | // 91 | Процедура УстановитьФорматированноеСообщение(Знач ПФорматированноеСообщение) Экспорт 92 | ФорматированноеСообщение = ПФорматированноеСообщение; 93 | КонецПроцедуры 94 | -------------------------------------------------------------------------------- /src/log-manager.os: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // LOGOS: реализация логирования в стиле log4j для OneScript 4 | // 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | Перем мСозданныеЛоги; 8 | Перем мИдентификаторыЛогов; 9 | Перем мНастройкиЛогирования; 10 | Перем мСпособыВывода; 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | // ПРОГРАММНЫЙ ИНТЕРФЕЙС 14 | 15 | Функция ПолучитьЛог(Знач ИмяЛога) Экспорт 16 | 17 | Если ИмяЛога = ИмяКорневогоЛога() Тогда 18 | ВызватьИсключение СтрШаблон("Имя %1 зарезервировано в подсистеме логирования и не должно использоваться явно.", ИмяЛога); 19 | КонецЕсли; 20 | 21 | Если мНастройкиЛогирования = Неопределено Тогда 22 | ОбновитьНастройки(); 23 | КонецЕсли; 24 | 25 | ОписаниеЛога = мСозданныеЛоги[ИмяЛога]; 26 | Если ОписаниеЛога = Неопределено Тогда 27 | ОписаниеЛога = НовыйДескрипторЛога(); 28 | ОписаниеЛога.Объект = Новый Лог(ИмяЛога); 29 | мСозданныеЛоги[ИмяЛога] = ОписаниеЛога; 30 | мИдентификаторыЛогов[ОписаниеЛога.Объект.ПолучитьИдентификатор()] = ИмяЛога; 31 | НастроитьЛог(ИмяЛога, ОписаниеЛога.Объект); 32 | КонецЕсли; 33 | 34 | ОписаниеЛога.СчетчикСсылок = ОписаниеЛога.СчетчикСсылок + 1; 35 | 36 | Возврат ОписаниеЛога.Объект; 37 | 38 | КонецФункции 39 | 40 | Процедура ЗакрытьЛог(Знач ОбъектЛога) Экспорт 41 | 42 | Идентификатор = ОбъектЛога.ПолучитьИдентификатор(); 43 | ИмяЛога = мИдентификаторыЛогов[Идентификатор]; 44 | Если ИмяЛога = Неопределено Тогда 45 | ОбъектЛога.Закрыть(); // Лог не создавался менеджером 46 | Возврат; 47 | КонецЕсли; 48 | 49 | ОписаниеЛога = мСозданныеЛоги[ИмяЛога]; 50 | Если ОписаниеЛога <> Неопределено Тогда 51 | ОписаниеЛога.СчетчикСсылок = ОписаниеЛога.СчетчикСсылок - 1; 52 | Если ОписаниеЛога.СчетчикСсылок <= 0 Тогда 53 | ОписаниеЛога.Объект.Закрыть(); 54 | мСозданныеЛоги.Удалить(ИмяЛога); 55 | мИдентификаторыЛогов.Удалить(Идентификатор); 56 | КонецЕсли; 57 | КонецЕсли; 58 | 59 | КонецПроцедуры 60 | 61 | Функция СписокСозданныхЛогов(Знач СтрокаФильтр = Неопределено) Экспорт 62 | 63 | СписокЛогов = Новый Массив(); 64 | 65 | Для каждого КлючИЗначение Из мСозданныеЛоги Цикл 66 | 67 | Если ЗначениеЗаполнено(СтрокаФильтр) Тогда 68 | 69 | ИмяЛога = КлючИЗначение.Ключ; 70 | 71 | Если НЕ СтрНачинаетсяС(ИмяЛога, СтрокаФильтр) Тогда 72 | Продолжить; 73 | КонецЕсли; 74 | 75 | СписокЛогов.Добавить(КлючИЗначение.Ключ); 76 | 77 | иначе 78 | 79 | СписокЛогов.Добавить(КлючИЗначение.Ключ); 80 | 81 | КонецЕсли; 82 | 83 | КонецЦикла; 84 | 85 | Возврат СписокЛогов; 86 | 87 | КонецФункции 88 | 89 | Функция НайтиСпособВыводаПоИмени(ИмяСпособаВывода) Экспорт 90 | Возврат мСпособыВывода[ИмяСпособаВывода]; 91 | КонецФункции 92 | 93 | Процедура ЗарегистрироватьСпособВывода(ИмяСпособаВывода, СпособВывода) Экспорт 94 | 95 | ТекущийСпособВывода = НайтиСпособВыводаПоИмени(ИмяСпособаВывода); 96 | 97 | Если НЕ ТекущийСпособВывода = Неопределено И НЕ ТекущийСпособВывода = СпособВывода Тогда 98 | ВызватьИсключение СтрШаблон("Способ вывода с именем %1 уже зарегистрирован", ИмяСпособаВывода); 99 | КонецЕсли; 100 | 101 | мСпособыВывода.Вставить(ИмяСпособаВывода, СпособВывода); 102 | 103 | КонецПроцедуры 104 | 105 | Функция СокращенноеИмяЛога(Знач ИмяЛога) Экспорт 106 | Возврат ФорматироватьИмяЛога(ИмяЛога); 107 | КонецФункции 108 | 109 | Функция ПолучитьНастройки() Экспорт 110 | Возврат мНастройкиЛогирования; 111 | КонецФункции 112 | 113 | Функция ФорматироватьИмяЛога(Знач ИмяЛога) 114 | 115 | КоличествоСимволов = 20; 116 | Результат = ""; 117 | 118 | ИтоговаяДлинаЛога = СтрДлина(ИмяЛога); 119 | Если ИтоговаяДлинаЛога <= КоличествоСимволов Тогда 120 | Возврат ИмяЛога; 121 | КонецЕсли; 122 | 123 | УзлыЛога = СтрРазделить(ИмяЛога, "."); 124 | 125 | Если УзлыЛога.Количество() = 1 Тогда 126 | Результат = СократитьСтроку(ИмяЛога, КоличествоСимволов); 127 | Возврат Результат; 128 | КонецЕсли; 129 | 130 | НеобходимоСокращатьУзелЛога = Истина; 131 | сч = 0; 132 | Для Каждого УзелЛога Из УзлыЛога Цикл 133 | 134 | ПоследнийУзелЛога = сч = УзлыЛога.ВГраница(); 135 | 136 | Если НеобходимоСокращатьУзелЛога Тогда 137 | Если ПоследнийУзелЛога Тогда 138 | РезультирующийУзелЛога = СократитьСтроку(УзелЛога, Макс(1, КоличествоСимволов - СтрДлина(Результат))); 139 | Иначе 140 | РезультирующийУзелЛога = Лев(УзелЛога, 1); 141 | КонецЕсли; 142 | Иначе 143 | РезультирующийУзелЛога = УзелЛога; 144 | КонецЕсли; 145 | 146 | Результат = Результат + РезультирующийУзелЛога + "."; 147 | ИтоговаяДлинаЛога = ИтоговаяДлинаЛога - (СтрДлина(УзелЛога) - 1); 148 | 149 | Если ИтоговаяДлинаЛога <= КоличествоСимволов Тогда 150 | НеобходимоСокращатьУзелЛога = Ложь; 151 | КонецЕсли; 152 | 153 | сч = сч + 1; 154 | КонецЦикла; 155 | 156 | Результат = Лев(Результат, СтрДлина(Результат) - 1); 157 | 158 | Возврат Результат; 159 | 160 | КонецФункции 161 | 162 | Функция СократитьСтроку(Знач ИсходнаяСтрока, Знач КоличествоСимволов) 163 | 164 | Результат = ИсходнаяСтрока; 165 | 166 | Если СтрДлина(Результат) <= КоличествоСимволов Тогда 167 | Возврат Результат; 168 | КонецЕсли; 169 | 170 | Результат = "~" + Прав(Результат, Макс(КоличествоСимволов - 1, 1)); 171 | 172 | Возврат Результат; 173 | 174 | КонецФункции 175 | 176 | Процедура ОбновитьНастройки() Экспорт 177 | 178 | КонфигИзСреды = Неопределено; 179 | 180 | КонфигИзСреды = ПолучитьПеременнуюСреды("LOGOS_CONFIG"); 181 | Если Не ЗначениеЗаполнено(КонфигИзСреды) Тогда 182 | УровеньЛогаИзСреды = ПолучитьПеременнуюСреды("LOGOS_LEVEL"); 183 | Если ЗначениеЗаполнено(УровеньЛогаИзСреды) Тогда 184 | КонфигИзСреды = СтрШаблон("logger.rootLogger=%1", УровеньЛогаИзСреды); 185 | КонецЕсли; 186 | КонецЕсли; 187 | 188 | мНастройкиЛогирования = Новый НастройкиЛогирования(); 189 | Если ЗначениеЗаполнено(КонфигИзСреды) Тогда 190 | КонфигИзСреды = СтрЗаменить(КонфигИзСреды, ";", Символы.ПС); 191 | мНастройкиЛогирования.ПрочитатьИзСтроки(КонфигИзСреды); 192 | Иначе 193 | КаталогКонфига = СтартовыйСценарий().Каталог; 194 | ФайлКонфига = Новый Файл(ОбъединитьПути(КаталогКонфига, "logos.cfg")); 195 | Если ФайлКонфига.Существует() Тогда 196 | мНастройкиЛогирования.Прочитать(ФайлКонфига.ПолноеИмя); 197 | КонецЕсли; 198 | КонецЕсли; 199 | 200 | КонецПроцедуры 201 | 202 | ////////////////////////////////////////////////////////////////////////// 203 | // ПРОЦЕДУРЫ МОДУЛЯ 204 | 205 | Процедура НастроитьЛог(Знач ИмяЛога, Знач ОбъектЛога) 206 | 207 | КорневаяНастройка = мНастройкиЛогирования.Получить(ИмяКорневогоЛога()); 208 | ПрименитьНастройку(ОбъектЛога, КорневаяНастройка); 209 | 210 | Настройка = мНастройкиЛогирования.Получить(ИмяЛога); 211 | Если Настройка = Неопределено Тогда 212 | Настройка = НайтиНастройкуВышеПоИерахии(ИмяЛога, ОбъектЛога); 213 | КонецЕсли; 214 | 215 | ПрименитьНастройку(ОбъектЛога, Настройка); 216 | 217 | КонецПроцедуры 218 | Функция НайтиНастройкуВышеПоИерахии(Знач ИмяЛога, Знач ОбъектЛога) 219 | 220 | ИерархияИмен = ПолучитьИерархиюИменЛогов(ИмяЛога); 221 | 222 | Для каждого ТекущееИмя Из ИерархияИмен Цикл 223 | Настройка = мНастройкиЛогирования.Получить(ТекущееИмя); 224 | Если НЕ Настройка = Неопределено Тогда 225 | Возврат Настройка; 226 | КонецЕсли; 227 | КонецЦикла; 228 | 229 | Возврат Неопределено; 230 | 231 | КонецФункции 232 | 233 | Функция ПолучитьИерархиюИменЛогов(Знач ИмяЛога) 234 | ЧастиИмени = СтрРазделить(ИмяЛога, "."); 235 | Если ЧастиИмени.Количество() = 1 Тогда 236 | Возврат Новый Массив; 237 | КонецЕсли; 238 | 239 | Результат = Новый Массив(); 240 | 241 | Для _Счетчик = 1 По ЧастиИмени.ВГраница() Цикл 242 | СрезМассива = СрезМассива(ЧастиИмени, 0, ЧастиИмени.ВГраница() - _Счетчик); 243 | Результат.Добавить(СтрСоединить(СрезМассива, ".")); 244 | КонецЦикла; 245 | 246 | Возврат Результат; 247 | КонецФункции 248 | 249 | Функция СрезМассива(Массив, НачальныйЭлемент, КонечныйЭлемент) 250 | Срез = Новый Массив(); 251 | 252 | Для _Счетчик = НачальныйЭлемент По КонечныйЭлемент Цикл 253 | Срез.Добавить(Массив[_Счетчик]); 254 | КонецЦикла; 255 | 256 | Возврат Срез; 257 | КонецФункции 258 | 259 | Процедура ПрименитьНастройку(Знач ОбъектЛога, Знач Настройка) 260 | 261 | Если Настройка = Неопределено Тогда 262 | Возврат; 263 | КонецЕсли; 264 | 265 | Если Настройка.Уровень <> Неопределено Тогда 266 | ОбъектЛога.УстановитьУровень(Настройка.Уровень); 267 | КонецЕсли; 268 | 269 | Для Каждого СпособВывода Из Настройка.СпособыВывода Цикл 270 | Описание = СпособВывода.Значение; 271 | ОбъектСпособаВывода = НайтиСпособВыводаПоИмени(СпособВывода.Ключ); 272 | Если ОбъектСпособаВывода = Неопределено Тогда 273 | ОбъектСпособаВывода = Новый(Описание.Класс); 274 | Для Каждого КлючИЗначение Из Описание.Свойства Цикл 275 | ОбъектСпособаВывода.УстановитьСвойство(КлючИЗначение.Ключ, КлючИЗначение.Значение); 276 | КонецЦикла; 277 | ЗарегистрироватьСпособВывода(СпособВывода.Ключ, ОбъектСпособаВывода); 278 | КонецЕсли; 279 | ОбъектЛога.ДобавитьСпособВывода(ОбъектСпособаВывода, Описание.Уровень); 280 | КонецЦикла; 281 | 282 | КонецПроцедуры 283 | 284 | Функция НовыйДескрипторЛога() 285 | 286 | Описание = Новый Структура; 287 | Описание.Вставить("Объект", Неопределено); 288 | Описание.Вставить("СчетчикСсылок", 0); 289 | 290 | Возврат Описание; 291 | 292 | КонецФункции 293 | 294 | Процедура Инициализация() 295 | 296 | мСозданныеЛоги = Новый Соответствие; 297 | мИдентификаторыЛогов = Новый Соответствие; 298 | мСпособыВывода = Новый Соответствие(); 299 | 300 | КонецПроцедуры 301 | 302 | Функция ИмяКорневогоЛога() 303 | Возврат "rootLogger"; 304 | КонецФункции 305 | 306 | /////////////////////////////////////////////////////////////////////////// 307 | 308 | Инициализация(); -------------------------------------------------------------------------------- /src/log-options.os: -------------------------------------------------------------------------------- 1 | #Использовать asserts 2 | 3 | Перем мПрочитанныеНастройкиЛоггеров; 4 | Перем мПрочитанныеСпособыВывода; 5 | Перем мНастройкиЛогирования; 6 | Перем мКартаУровней; 7 | 8 | // Читает настройки из конфигурационного файла 9 | // 10 | Процедура Прочитать(Знач ИмяФайла) Экспорт 11 | 12 | Документ = Новый ТекстовыйДокумент; 13 | Документ.Прочитать(ИмяФайла); 14 | ПрочитатьКонфигурацию(Документ); 15 | 16 | КонецПроцедуры // Прочитать(Знач ИмяФайла) 17 | 18 | Процедура ПрочитатьИзСтроки(Знач Строка) Экспорт 19 | Документ = Новый ТекстовыйДокумент; 20 | Документ.УстановитьТекст(Строка); 21 | ПрочитатьКонфигурацию(Документ); 22 | КонецПроцедуры 23 | 24 | Процедура ПрочитатьКонфигурацию(Знач Документ) 25 | мПрочитанныеСпособыВывода = Новый Соответствие; 26 | мПрочитанныеНастройкиЛоггеров = Новый Соответствие; 27 | 28 | Для Сч = 1 По Документ.КоличествоСтрок() Цикл 29 | СтрокаНастроек = Документ.ПолучитьСтроку(Сч); 30 | 31 | ОбработатьСтрокуНастроек(СтрокаНастроек); 32 | 33 | КонецЦикла; 34 | 35 | СоздатьОбъектыНастроек(); 36 | 37 | КонецПроцедуры 38 | 39 | // Получает опции по которым будет настроен логгер 40 | // 41 | Функция Получить(Знач ИмяЛоггера) Экспорт 42 | 43 | Если мНастройкиЛогирования = Неопределено Тогда 44 | Возврат Неопределено; 45 | Иначе 46 | Возврат мНастройкиЛогирования[ИмяЛоггера]; 47 | КонецЕсли; 48 | 49 | КонецФункции 50 | 51 | Процедура ОбработатьСтрокуНастроек(Знач СтрокаНастроек) 52 | 53 | Если Лев(СтрокаНастроек, 1) = "#" Или ПустаяСтрока(СтрокаНастроек) Тогда 54 | // # это комментарий 55 | Возврат; 56 | КонецЕсли; 57 | 58 | Поз = Найти(СтрокаНастроек, "="); 59 | Если Поз = 0 Тогда 60 | ВызватьИсключение "Неверный формат строки настроек: " + СтрокаНастроек; 61 | КонецЕсли; 62 | 63 | Ключ = Лев(СтрокаНастроек, Поз-1); 64 | Значение = Сред(СтрокаНастроек, Поз+1); 65 | 66 | КлассНастроек = ОчереднойФрагмент(Ключ); 67 | 68 | Если ПустаяСтрока(Ключ) Тогда 69 | ВызватьИсключение "Неверная строка настроек, нет опций у класса: " + КлассНастроек; 70 | КонецЕсли; 71 | 72 | ОбработатьКлассНастроек(КлассНастроек, Ключ, Значение); 73 | 74 | КонецПроцедуры 75 | 76 | Процедура СоздатьОбъектыНастроек() 77 | 78 | мНастройкиЛогирования = Новый Соответствие; 79 | КартаУровней = КартаУровней(); 80 | 81 | Для каждого ОбъявленныйЛоггер Из мПрочитанныеНастройкиЛоггеров Цикл 82 | 83 | Настройка = Новый Структура; 84 | Настройка.Вставить("Уровень", КартаУровней[ОбъявленныйЛоггер.Значение.Уровень]); 85 | Настройка.Вставить("СпособыВывода", Новый Соответствие); 86 | 87 | Для Каждого ПривязанныйСпособВывода Из ОбъявленныйЛоггер.Значение.Аппендеры Цикл 88 | Аппендер = мПрочитанныеСпособыВывода[ПривязанныйСпособВывода]; 89 | Если Аппендер = Неопределено Тогда 90 | ВызватьИсключение СтрШаблон("К логу {%1} привязан способ вывода {%2}, но этот способ нигде не описан", 91 | ОбъявленныйЛоггер.Ключ, 92 | ПривязанныйСпособВывода); 93 | КонецЕсли; 94 | 95 | Настройка.СпособыВывода.Вставить(ПривязанныйСпособВывода, Аппендер); 96 | 97 | КонецЦикла; 98 | 99 | мНастройкиЛогирования.Вставить(ОбъявленныйЛоггер.Ключ, Настройка); 100 | 101 | КонецЦикла; 102 | 103 | КонецПроцедуры 104 | 105 | Функция ОчереднойФрагмент(Ключ, Разделитель=".") 106 | Поз = Найти(Ключ, Разделитель); 107 | Если Поз > 0 Тогда 108 | Ответ = Лев(Ключ, Поз-1); 109 | Ключ = Сред(Ключ, Поз+1); 110 | Иначе 111 | Ответ = Ключ; 112 | Ключ = ""; 113 | КонецЕсли; 114 | 115 | Возврат Ответ; 116 | КонецФункции // ОчереднойФрагмент(Ключ) 117 | 118 | Процедура ОбработатьКлассНастроек(Знач КлассНастроек, Знач Ключ, Знач Значение) 119 | 120 | Если КлассНастроек = "logger" Тогда 121 | ОбработатьНастройкуЛоггера(Ключ, Значение); 122 | ИначеЕсли КлассНастроек = "appender" Тогда 123 | ОбработатьНастройкуСпособаВывода(Ключ, Значение); 124 | Иначе 125 | ВызватьИсключение "Неизвестный класс настроек: " + КлассНастроек; 126 | КонецЕсли 127 | 128 | КонецПроцедуры 129 | 130 | Процедура ОбработатьНастройкуЛоггера(Знач Ключ, Знач Значение) 131 | 132 | ПрочитаннаяНастройка = Новый Структура; 133 | ПрочитаннаяНастройка.Вставить("Уровень"); 134 | ПрочитаннаяНастройка.Вставить("Аппендеры"); 135 | мПрочитанныеНастройкиЛоггеров.Вставить(Ключ, ПрочитаннаяНастройка); 136 | 137 | ПрочитаннаяНастройка.Уровень = СокрЛП(ОчереднойФрагмент(Значение, ",")); 138 | Если Не ИзвестныйУровеньЛога(ПрочитаннаяНастройка.Уровень) Тогда 139 | ВызватьИсключение "Неизвестный уровень лога: " + ПрочитаннаяНастройка.Уровень; 140 | КонецЕсли; 141 | 142 | ПрочитаннаяНастройка.Аппендеры = Новый Массив; 143 | Пока Не ПустаяСтрока(Значение) Цикл 144 | Аппендер = СокрЛП(ОчереднойФрагмент(Значение, ",")); 145 | Если Не ПустаяСтрока(Аппендер) Тогда 146 | ПрочитаннаяНастройка.Аппендеры.Добавить(Аппендер); 147 | КонецЕсли; 148 | КонецЦикла; 149 | 150 | КонецПроцедуры 151 | 152 | Процедура ОбработатьНастройкуСпособаВывода(Знач Ключ, Знач Значение) 153 | 154 | ИмяАппендера = ОчереднойФрагмент(Ключ); 155 | Если ПустаяСтрока(Ключ) Тогда 156 | // это объявление аппендера, обязательный элемент 157 | ОписаниеАппендера = Новый Структура; 158 | ОписаниеАппендера.Вставить("Класс", Значение); 159 | ОписаниеАппендера.Вставить("Уровень", УровниЛога.Информация); 160 | ОписаниеАппендера.Вставить("Свойства", Новый Соответствие); 161 | мПрочитанныеСпособыВывода[ИмяАппендера] = ОписаниеАппендера; 162 | Иначе 163 | // это свойство аппендера, сам аппендер обязан быть описан ранее 164 | НастройкаАппендера = мПрочитанныеСпособыВывода[ИмяАппендера]; 165 | Если НастройкаАппендера = Неопределено Тогда 166 | ВызватьИсключение СтрШаблон("Неверная структура файла. Класс способа вывода {%1} должен быть описан ранее строки {%2}", 167 | ИмяАппендера, 168 | ИмяАппендера + "." + Ключ); 169 | КонецЕсли; 170 | Если НРег(Ключ) = НРег(ИМЯ_КЛЮЧА_УРОВЕНЬ()) Тогда 171 | НовыйУровень = КартаУровней().Получить(Значение); 172 | Если НовыйУровень = Неопределено Тогда 173 | ВызватьИсключение "Не нашли уровень по ключу " + Значение; 174 | КонецЕсли; 175 | 176 | НастройкаАппендера.Вставить("Уровень", НовыйУровень); 177 | Иначе 178 | НастройкаАппендера.Свойства.Вставить(Ключ, Значение); 179 | КонецЕсли; 180 | КонецЕсли; 181 | 182 | КонецПроцедуры 183 | 184 | Функция КартаУровней() 185 | Если Не ЗначениеЗаполнено(мКартаУровней) Тогда 186 | 187 | КартаУровней = Новый Соответствие; 188 | КартаУровней.Вставить("DEBUG", УровниЛога.Отладка); 189 | КартаУровней.Вставить("INFO", УровниЛога.Информация); 190 | КартаУровней.Вставить("WARN", УровниЛога.Предупреждение); 191 | КартаУровней.Вставить("ERROR", УровниЛога.Ошибка); 192 | КартаУровней.Вставить("CRITICALERROR", УровниЛога.КритичнаяОшибка); 193 | КартаУровней.Вставить("DISABLE", УровниЛога.Отключить); 194 | 195 | мКартаУровней = Новый ФиксированноеСоответствие(КартаУровней); 196 | 197 | КонецЕсли; 198 | 199 | Возврат мКартаУровней; 200 | КонецФункции 201 | 202 | Функция ИзвестныйУровеньЛога(Знач ИмяУровня) 203 | 204 | ДопустимыеУровни = "DEFAULT,DEBUG,INFO,WARN,ERROR,CRITICALERROR,DISABLE,"; 205 | Возврат Найти(ДопустимыеУровни, ИмяУровня+",") > 0; 206 | 207 | КонецФункции 208 | 209 | Функция ИМЯ_КЛЮЧА_УРОВЕНЬ() 210 | Возврат "level"; 211 | КонецФункции -------------------------------------------------------------------------------- /src/log.os: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////////// 2 | // 3 | // LOGOS: реализация логирования в стиле log4j для OneScript 4 | // 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | Перем мИмяЛога; 8 | Перем мТекущийУровень; 9 | Перем мСпособыВывода; 10 | Перем мСпособВыводаЗаданВручную; 11 | Перем мУровниАппендеров; 12 | Перем НастройкаВыводаСообщений; 13 | 14 | Перем мИдентификатор; 15 | Перем мРаскладкаСообщения; 16 | Перем мВерсияAPIРаскладкиСообщения; 17 | Перем мДополнительныеПоляЛога; 18 | Перем мВложенныеЛоги; 19 | 20 | Процедура ПриСозданииОбъекта(пИмяЛога) 21 | мИмяЛога = пИмяЛога; 22 | КонецПроцедуры 23 | 24 | Функция Уровень() Экспорт 25 | Возврат мТекущийУровень; 26 | КонецФункции 27 | 28 | Функция Поля(Поле1 = Неопределено, ЗначениеПоля1 = Неопределено, 29 | Поле2 = Неопределено, ЗначениеПоля2 = Неопределено, 30 | Поле3 = Неопределено, ЗначениеПоля3 = Неопределено, 31 | Поле4 = Неопределено, ЗначениеПоля4 = Неопределено 32 | ) Экспорт 33 | 34 | 35 | НаборПолей = Новый Соответствие(); 36 | 37 | Если НЕ Поле1 = Неопределено Тогда 38 | НаборПолей.Вставить(Поле1, ЗначениеПоля1); 39 | КонецЕсли; 40 | Если НЕ Поле2 = Неопределено Тогда 41 | НаборПолей.Вставить(Поле2, ЗначениеПоля2); 42 | КонецЕсли; 43 | Если НЕ Поле3 = Неопределено Тогда 44 | НаборПолей.Вставить(Поле3, ЗначениеПоля3); 45 | КонецЕсли; 46 | Если НЕ Поле4 = Неопределено Тогда 47 | НаборПолей.Вставить(Поле4, ЗначениеПоля4); 48 | КонецЕсли; 49 | 50 | Возврат ПоляИз(НаборПолей); 51 | 52 | КонецФункции 53 | 54 | Функция ПоляИз(Знач НаборПолей, Знач КлючиИсключения = "") Экспорт 55 | 56 | ЛогСПолями = Новый Лог(мИмяЛога); 57 | ЛогСПолями.УстановитьРаскладку(мРаскладкаСообщения); 58 | ЛогСПолями.УстановитьУровень(мТекущийУровень); 59 | 60 | Если мСпособВыводаЗаданВручную Тогда 61 | Для каждого СпособВыбора Из мСпособыВывода Цикл 62 | 63 | ЛогСПолями.ДобавитьСпособВывода(СпособВыбора, мУровниАппендеров[СпособВыбора].Уровень); 64 | 65 | КонецЦикла; 66 | КонецЕсли; 67 | 68 | ДополнительныеПоля = Новый Соответствие(); 69 | 70 | Если мДополнительныеПоляЛога.Количество() > 0 Тогда 71 | 72 | Для каждого ПолеРодителя Из мДополнительныеПоляЛога Цикл 73 | ДополнительныеПоля.Вставить(ПолеРодителя.Ключ, ПолеРодителя.Значение); 74 | КонецЦикла; 75 | 76 | КонецЕсли; 77 | 78 | МассивКлючейИсключения = ПолучитьМассивКлючейИсключения(КлючиИсключения); 79 | 80 | Для каждого ПолеНабора Из НаборПолей Цикл 81 | 82 | Если МассивКлючейИсключения.Количество() > 0 83 | И Не МассивКлючейИсключения.Найти(ПолеНабора.Ключ) = Неопределено Тогда 84 | Продолжить; 85 | КонецЕсли; 86 | 87 | ДополнительныеПоля.Вставить(ПолеНабора.Ключ, ПолеНабора.Значение); 88 | КонецЦикла; 89 | 90 | ЛогСПолями.ДополнительныеПоля(ДополнительныеПоля); 91 | 92 | мВложенныеЛоги.Добавить(ЛогСПолями); 93 | 94 | Возврат ЛогСПолями; 95 | 96 | КонецФункции 97 | 98 | Функция ПолучитьМассивКлючейИсключения(Знач КлючиИсключения) 99 | 100 | МассивКлючей = Новый Массив(); 101 | 102 | Если Не ЗначениеЗаполнено(КлючиИсключения) Тогда 103 | Возврат МассивКлючей; 104 | КонецЕсли; 105 | 106 | МассивКлючейИсключения = СтрРазделить(КлючиИсключения, ","); 107 | 108 | Для каждого ЭлементМассива Из МассивКлючейИсключения Цикл 109 | МассивКлючей.Добавить(СокрЛП(ЭлементМассива)); 110 | КонецЦикла; 111 | 112 | Возврат МассивКлючей 113 | 114 | КонецФункции 115 | 116 | Процедура ДополнительныеПоля(пДополнительныеПоля) Экспорт 117 | мДополнительныеПоляЛога = пДополнительныеПоля; 118 | КонецПроцедуры 119 | 120 | Процедура УстановитьУровень(Знач Уровень) Экспорт 121 | Если Уровень < 0 Или Уровень > УровниЛога.Отключить Тогда 122 | ВызватьИсключение "Неверное значение аргумента 'Уровень'"; 123 | КонецЕсли; 124 | 125 | мТекущийУровень = Уровень; 126 | 127 | МинимальныйУровень = Уровень; 128 | 129 | Если ЗначениеЗаполнено(мУровниАппендеров) Тогда 130 | Для каждого КлючЗначение Из мУровниАппендеров Цикл 131 | СпособВывода = КлючЗначение.Ключ; 132 | НастройкаСпособаВывода = КлючЗначение.Значение; 133 | Если Не НастройкаСпособаВывода.ЗаданЯвно Тогда 134 | НастройкаСпособаВывода.Уровень = Уровень; 135 | КонецЕсли; 136 | 137 | Если НастройкаСпособаВывода.Уровень < Уровень Тогда 138 | МинимальныйУровень = НастройкаСпособаВывода.Уровень; 139 | КонецЕсли; 140 | КонецЦикла; 141 | 142 | КонецЕсли; 143 | 144 | ЗаполнитьНастройкуВыводаСообщений(МинимальныйУровень); 145 | 146 | Для каждого ВложенныйЛог Из мВложенныеЛоги Цикл 147 | ВложенныйЛог.УстановитьУровень(Уровень); 148 | КонецЦикла; 149 | 150 | КонецПроцедуры 151 | 152 | Процедура УстановитьРаскладку(Знач Раскладка) Экспорт 153 | мРаскладкаСообщения = Раскладка; 154 | ОпределитьВерсиюAPIРаскладкиСообщения(); 155 | 156 | Для каждого ВложенныйЛог Из мВложенныеЛоги Цикл 157 | ВложенныйЛог.УстановитьРаскладку(Раскладка); 158 | КонецЦикла; 159 | 160 | КонецПроцедуры 161 | 162 | Процедура Закрыть() Экспорт 163 | Для Каждого СпособВывода Из мСпособыВывода Цикл 164 | СпособВывода.Закрыть(); 165 | КонецЦикла; 166 | мСпособыВывода.Очистить(); 167 | мУровниАппендеров.Очистить(); 168 | 169 | Для каждого ВложенныйЛог Из мВложенныеЛоги Цикл 170 | ВложенныйЛог.Закрыть(); 171 | КонецЦикла; 172 | 173 | КонецПроцедуры 174 | 175 | // Возвращает признак ручного/собственного задания способа вывода 176 | // 177 | // Возвращаемое значение: 178 | // Булево - Истина, если добавляли свои способы вывода, и Ложь, если не добавляли 179 | // 180 | Функция ДобавленыСобственныеСпособыВывода() Экспорт 181 | Возврат мСпособВыводаЗаданВручную; 182 | КонецФункции 183 | 184 | Процедура ДобавитьСпособВывода(Знач СпособВывода, Знач НовыйУровеньСпособаВывода = Неопределено) Экспорт 185 | 186 | Если Не мСпособВыводаЗаданВручную Тогда 187 | Закрыть(); 188 | мСпособВыводаЗаданВручную = Истина; 189 | КонецЕсли; 190 | 191 | мСпособыВывода.Добавить(СпособВывода); 192 | 193 | Если НовыйУровеньСпособаВывода <> Неопределено Тогда 194 | НовыйУровень = НовыйУровеньСпособаВывода; 195 | ЗаданЯвно = Истина; 196 | 197 | УточнитьНастройкуВыводаСообщенийДляНовогоУровня(НовыйУровень); 198 | Иначе 199 | НовыйУровень = Уровень(); 200 | ЗаданЯвно = Ложь; 201 | КонецЕсли; 202 | 203 | НастройкаСпособаВывода = НоваяНастройкаСпособаВывода(НовыйУровень, ЗаданЯвно); 204 | мУровниАппендеров[СпособВывода] = НастройкаСпособаВывода; 205 | 206 | ПроверитьПоддержкуAPIВывести(СпособВывода, НастройкаСпособаВывода); 207 | 208 | Для каждого ВложенныйЛог Из мВложенныеЛоги Цикл 209 | ВложенныйЛог.ДобавитьСпособВывода(СпособВывода, НовыйУровеньСпособаВывода); 210 | КонецЦикла; 211 | 212 | КонецПроцедуры 213 | 214 | Процедура ПроверитьПоддержкуAPIВывести(СпособВывода, НастройкаСпособаВывода) 215 | Рефлектор = Новый Рефлектор; 216 | Методы = Рефлектор.ПолучитьТаблицуМетодов(СпособВывода); 217 | 218 | МетодВывестиСобытие = Методы.Найти("ВывестиСобытие"); 219 | Если МетодВывестиСобытие <> Неопределено Тогда 220 | НастройкаСпособаВывода.ВерсияAPI = 3; 221 | Возврат; 222 | КонецЕсли; 223 | 224 | МетодВывести = Методы.Найти("Вывести"); 225 | Если МетодВывести <> Неопределено Тогда 226 | Если МетодВывести.КоличествоПараметров = 2 Тогда 227 | НастройкаСпособаВывода.ВерсияAPI = 2; 228 | Иначе 229 | Сообщить("Число параметров:" + МетодВывести.КоличествоПараметров); 230 | СпособВывода.Вывести("Метод Вывести должен иметь 2 параметра. 231 | |В будущих версиях logos данный способ вывода перестанет работать."); 232 | КонецЕсли; 233 | КонецЕсли; 234 | КонецПроцедуры 235 | 236 | Процедура ОпределитьВерсиюAPIРаскладкиСообщения() 237 | мВерсияAPIРаскладкиСообщения = 1; 238 | 239 | Рефлектор = Новый Рефлектор; 240 | Методы = Рефлектор.ПолучитьТаблицуМетодов(мРаскладкаСообщения); 241 | МетодПолучитьФорматированноеСообщение = Методы.Найти("ПолучитьФорматированноеСообщение"); 242 | Если МетодПолучитьФорматированноеСообщение <> Неопределено Тогда 243 | мВерсияAPIРаскладкиСообщения = 2; 244 | КонецЕсли; 245 | КонецПроцедуры 246 | 247 | Процедура УдалитьСпособВывода(Знач СпособВывода) Экспорт 248 | 249 | Для Сч = 0 По мСпособыВывода.Количество()-1 Цикл 250 | Если мСпособыВывода[Сч] = СпособВывода Тогда 251 | мУровниАппендеров.Удалить(СпособВывода); 252 | СпособВывода.Закрыть(); 253 | мСпособыВывода.Удалить(Сч); 254 | Прервать; 255 | КонецЕсли; 256 | КонецЦикла; 257 | 258 | Для каждого ВложенныйЛог Из мВложенныеЛоги Цикл 259 | ВложенныйЛог.УдалитьСпособВывода(СпособВывода); 260 | КонецЦикла; 261 | 262 | КонецПроцедуры 263 | 264 | Функция УровеньСпособаВывода(Знач СпособВывода) Экспорт 265 | РезУровень = мУровниАппендеров[СпособВывода].Уровень; 266 | Возврат РезУровень; 267 | КонецФункции 268 | 269 | Функция ПолучитьИдентификатор() Экспорт 270 | Возврат мИдентификатор; 271 | КонецФункции 272 | 273 | Процедура Отладка(Знач Сообщение, 274 | Знач Параметр1 = Неопределено, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, 275 | Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, 276 | Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт 277 | 278 | Вывести(Сообщение, УровниЛога.Отладка, Параметр1, 279 | Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9); 280 | КонецПроцедуры 281 | 282 | Процедура Информация(Знач Сообщение, 283 | Знач Параметр1 = Неопределено, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, 284 | Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, 285 | Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт 286 | 287 | Вывести(Сообщение, УровниЛога.Информация, Параметр1, 288 | Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9); 289 | 290 | КонецПроцедуры 291 | 292 | Процедура Предупреждение(Знач Сообщение, 293 | Знач Параметр1 = Неопределено, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, 294 | Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, 295 | Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт 296 | 297 | Вывести(Сообщение, УровниЛога.Предупреждение, Параметр1, 298 | Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9); 299 | 300 | КонецПроцедуры 301 | 302 | Процедура Ошибка(Знач Сообщение, 303 | Знач Параметр1 = Неопределено, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, 304 | Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, 305 | Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт 306 | 307 | Вывести(Сообщение, УровниЛога.Ошибка, Параметр1, 308 | Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9); 309 | 310 | КонецПроцедуры 311 | 312 | Процедура КритичнаяОшибка(Знач Сообщение, 313 | Знач Параметр1 = Неопределено, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, 314 | Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, 315 | Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт 316 | 317 | Вывести(Сообщение, УровниЛога.КритичнаяОшибка, Параметр1, 318 | Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9); 319 | 320 | КонецПроцедуры 321 | 322 | Процедура Вывести(Знач Сообщение, Знач УровеньСообщения, 323 | Знач Параметр1 = Неопределено, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, 324 | Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, 325 | Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) Экспорт 326 | 327 | ВыводитьСообщение = НастройкаВыводаСообщений[УровеньСообщения]; 328 | 329 | Если Не ВыводитьСообщение Тогда 330 | Возврат; 331 | КонецЕсли; 332 | 333 | Если ЕстьЗаполненныеПараметры(Параметр1, Параметр2, Параметр3, 334 | Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9) Тогда 335 | 336 | Сообщение = СтрШаблон(Сообщение, Параметр1, 337 | Параметр2, Параметр3, Параметр4, Параметр5, Параметр6, Параметр7, Параметр8, Параметр9); 338 | КонецЕсли; 339 | 340 | СтроительСобытияЛога = Новый СтроительСобытияЛога; 341 | СтроительСобытияЛога.УстановитьИмяЛога(мИмяЛога); 342 | СтроительСобытияЛога.УстановитьУровень(УровеньСообщения); 343 | СтроительСобытияЛога.УстановитьУровеньЛога(Уровень()); 344 | СтроительСобытияЛога.УстановитьСообщение(Сообщение); 345 | СтроительСобытияЛога.УстановитьВремяСобытия(ТекущаяУниверсальнаяДатаВМиллисекундах()); 346 | СтроительСобытияЛога.УстановитьДополнительныеПоля(мДополнительныеПоляЛога); 347 | 348 | СобытиеЛога = СтроительСобытияЛога.Создать(); 349 | 350 | Если мВерсияAPIРаскладкиСообщения = 2 Тогда 351 | ВыводимоеСообщение = мРаскладкаСообщения.ПолучитьФорматированноеСообщение(СобытиеЛога); 352 | Иначе 353 | ВыводимоеСообщение = мРаскладкаСообщения.Форматировать(СобытиеЛога.ПолучитьУровень(), СобытиеЛога.ПолучитьСообщение()); 354 | КонецЕсли; 355 | СобытиеЛога.УстановитьФорматированноеСообщение(ВыводимоеСообщение); 356 | 357 | Для Каждого СпособВывода Из мСпособыВывода Цикл 358 | НастройкаАппендера = мУровниАппендеров[СпособВывода]; 359 | УровеньСпособаВывода = НастройкаАппендера.Уровень; 360 | Если УровеньСпособаВывода = Неопределено Или УровеньСообщения >= УровеньСпособаВывода Тогда 361 | Если НастройкаАппендера.ВерсияAPI = 3 Тогда 362 | СпособВывода.ВывестиСобытие(СобытиеЛога); 363 | ИначеЕсли НастройкаАппендера.ВерсияAPI = 2 Тогда 364 | СпособВывода.Вывести(СобытиеЛога.ПолучитьФорматированноеСообщение(), СобытиеЛога.ПолучитьУровень()); 365 | Иначе 366 | СпособВывода.Вывести(СобытиеЛога.ПолучитьФорматированноеСообщение()); 367 | КонецЕсли; 368 | КонецЕсли; 369 | КонецЦикла; 370 | 371 | КонецПроцедуры 372 | 373 | Функция ЕстьЗаполненныеПараметры(Знач Параметр1 = Неопределено, Знач Параметр2 = Неопределено, Знач Параметр3 = Неопределено, 374 | Знач Параметр4 = Неопределено, Знач Параметр5 = Неопределено, Знач Параметр6 = Неопределено, 375 | Знач Параметр7 = Неопределено, Знач Параметр8 = Неопределено, Знач Параметр9 = Неопределено) 376 | 377 | Если НЕ Параметр1 = Неопределено Тогда 378 | Возврат Истина; 379 | ИначеЕсли НЕ Параметр2 = Неопределено Тогда 380 | Возврат Истина; 381 | ИначеЕсли НЕ Параметр3 = Неопределено Тогда 382 | Возврат Истина; 383 | ИначеЕсли НЕ Параметр4 = Неопределено Тогда 384 | Возврат Истина; 385 | ИначеЕсли НЕ Параметр5 = Неопределено Тогда 386 | Возврат Истина; 387 | ИначеЕсли НЕ Параметр6 = Неопределено Тогда 388 | Возврат Истина; 389 | ИначеЕсли НЕ Параметр7 = Неопределено Тогда 390 | Возврат Истина; 391 | ИначеЕсли НЕ Параметр8 = Неопределено Тогда 392 | Возврат Истина; 393 | ИначеЕсли НЕ Параметр9 = Неопределено Тогда 394 | Возврат Истина; 395 | КонецЕсли; 396 | 397 | Возврат Ложь; 398 | 399 | КонецФункции 400 | 401 | Процедура Инициализация() 402 | 403 | мВложенныеЛоги = Новый Массив(); 404 | мИдентификатор = Новый УникальныйИдентификатор; 405 | мДополнительныеПоляЛога = Новый Соответствие(); 406 | НастройкаВыводаСообщений = НоваяНастройкаВыводаСообщений(); 407 | 408 | УстановитьУровень(УровниЛога.Информация); 409 | ИнициализироватьСпособыВывода(); 410 | 411 | КонецПроцедуры 412 | 413 | Процедура ИнициализироватьСпособыВывода() 414 | 415 | УстановитьРаскладку(Новый ОсновнаяРаскладкаСообщения); 416 | 417 | мСпособВыводаЗаданВручную = Ложь; 418 | мСпособыВывода = Новый Массив; 419 | мУровниАппендеров = Новый Соответствие; 420 | 421 | ВыводПоУмолчанию = Новый ВыводЛогаВКонсоль(); 422 | мСпособыВывода.Добавить(ВыводПоУмолчанию); 423 | НастройкаСпособаВывода = НоваяНастройкаСпособаВывода(Уровень(), Ложь); 424 | мУровниАппендеров[ВыводПоУмолчанию] = НастройкаСпособаВывода; 425 | 426 | ПроверитьПоддержкуAPIВывести(ВыводПоУмолчанию, НастройкаСпособаВывода); 427 | 428 | КонецПроцедуры 429 | 430 | Функция НоваяНастройкаВыводаСообщений() 431 | Уровни = УровниЛога.Уровни(); 432 | Результат = Новый Массив(Уровни.Количество()); 433 | Для каждого КлючЗначение Из Уровни Цикл 434 | Результат[КлючЗначение.Значение] = Ложь; 435 | КонецЦикла; 436 | Возврат Результат; 437 | КонецФункции 438 | 439 | Процедура ЗаполнитьНастройкуВыводаСообщений(Знач МинимальныйУровень) 440 | Для УровеньФильтра = 0 По НастройкаВыводаСообщений.ВГраница() Цикл 441 | РазрешенВыводСообщений = УровеньФильтра >= МинимальныйУровень; 442 | НастройкаВыводаСообщений[УровеньФильтра] = РазрешенВыводСообщений; 443 | КонецЦикла; 444 | КонецПроцедуры 445 | 446 | Процедура УточнитьНастройкуВыводаСообщенийДляНовогоУровня(Знач НовыйУровень) 447 | Для УровеньФильтра = 0 По НастройкаВыводаСообщений.ВГраница() Цикл 448 | Если НовыйУровень <= УровеньФильтра Тогда 449 | РазрешенВыводСообщений = Истина; 450 | Иначе 451 | РазрешенВыводСообщений = НастройкаВыводаСообщений[УровеньФильтра]; 452 | КонецЕсли; 453 | НастройкаВыводаСообщений[УровеньФильтра] = РазрешенВыводСообщений; 454 | КонецЦикла; 455 | 456 | КонецПроцедуры 457 | 458 | Функция НоваяНастройкаСпособаВывода(Знач НовыйУровень, Знач ЗаданЯвно) 459 | 460 | НастройкаСпособаВывода = Новый Структура("Уровень, ЗаданЯвно, ВерсияAPI", НовыйУровень, ЗаданЯвно, Неопределено); 461 | Возврат НастройкаСпособаВывода; 462 | 463 | КонецФункции 464 | 465 | Инициализация(); 466 | -------------------------------------------------------------------------------- /src/standart-layouts.os: -------------------------------------------------------------------------------- 1 | Функция JSON() Экспорт 2 | 3 | РаскладкаСообщения = Новый JSONРаскладкаСообщения; 4 | 5 | Возврат РаскладкаСообщения; 6 | 7 | КонецФункции 8 | 9 | Функция Основная() Экспорт 10 | 11 | РаскладкаСообщения = Новый ОсновнаяРаскладкаСообщения; 12 | 13 | Возврат РаскладкаСообщения; 14 | 15 | КонецФункции -------------------------------------------------------------------------------- /tasks/coverage.os: -------------------------------------------------------------------------------- 1 | #Использовать coverage 2 | #Использовать 1commands 3 | #Использовать fs 4 | 5 | ФС.ОбеспечитьПустойКаталог("coverage"); 6 | ПутьКСтат = "coverage/stat.json"; 7 | 8 | Команда = Новый Команда; 9 | Команда.УстановитьКоманду("oscript"); 10 | Команда.ДобавитьПараметр("-encoding=utf-8"); 11 | Команда.ДобавитьПараметр(СтрШаблон("-codestat=%1", ПутьКСтат)); 12 | Команда.ДобавитьПараметр("tasks/test.os"); 13 | Команда.ПоказыватьВыводНемедленно(Истина); 14 | 15 | КодВозврата = Команда.Исполнить(); 16 | 17 | Файл_Стат = Новый Файл(ПутьКСтат); 18 | 19 | ИмяПакета = "logos"; 20 | 21 | ПроцессорГенерации = Новый ГенераторОтчетаПокрытия(); 22 | 23 | ПроцессорГенерации.ОтносительныеПути() 24 | .ФайлСтатистики(Файл_Стат.ПолноеИмя) 25 | .GenericCoverage() 26 | .Cobertura() 27 | .Clover(ИмяПакета) 28 | .Сформировать(); 29 | 30 | ЗавершитьРаботу(КодВозврата); -------------------------------------------------------------------------------- /tasks/test.os: -------------------------------------------------------------------------------- 1 | #Использовать ".." 2 | #Использовать 1bdd 3 | #Использовать 1testrunner 4 | 5 | Функция ПрогнатьТесты() 6 | 7 | Тестер = Новый Тестер; 8 | 9 | ПутьКТестам = ОбъединитьПути(ТекущийСценарий().Каталог, "..", "tests"); 10 | 11 | ФайлПутьКТестам = Новый Файл(ПутьКТестам); 12 | Если Не ФайлПутьКТестам.Существует() Тогда 13 | Сообщить("Не найден каталог тестов " + ПутьКТестам); 14 | Возврат Ложь; 15 | КонецЕсли; 16 | 17 | ПутьКОтчетуJUnit = ОбъединитьПути(ТекущийСценарий().Каталог, ".."); 18 | 19 | РезультатТестирования = Тестер.ТестироватьКаталог( 20 | Новый Файл(ПутьКТестам), 21 | Новый Файл(ПутьКОтчетуJUnit) 22 | ); 23 | 24 | Успешно = РезультатТестирования = 0; 25 | 26 | Возврат Успешно; 27 | КонецФункции // ПрогнатьТесты() 28 | 29 | Функция ПрогнатьФичи() 30 | 31 | ПутьОтчетаJUnit = "./bdd-log.xml"; 32 | 33 | КаталогФич = ОбъединитьПути(".", "features"); 34 | 35 | ИсполнительБДД = Новый ИсполнительБДД; 36 | 37 | Файл_КаталогФич = Новый Файл(КаталогФич); 38 | Если Не Файл_КаталогФич.Существует() Тогда 39 | Сообщить("Не найден каталог фич " + КаталогФич); 40 | Возврат Истина; 41 | КонецЕсли; 42 | 43 | РезультатыВыполнения = ИсполнительБДД.ВыполнитьФичу(Файл_КаталогФич, Файл_КаталогФич); 44 | ИтоговыйРезультатВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); 45 | 46 | СтатусВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения().НеВыполнялся; 47 | Если РезультатыВыполнения.Строки.Количество() > 0 Тогда 48 | 49 | СтатусВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); 50 | 51 | КонецЕсли; 52 | 53 | ГенераторОтчетаJUnit = Новый ГенераторОтчетаJUnit; 54 | ГенераторОтчетаJUnit.Сформировать(РезультатыВыполнения, СтатусВыполнения, ПутьОтчетаJUnit); 55 | 56 | Сообщить(СтрШаблон("Результат прогона фич <%1> 57 | |", ИтоговыйРезультатВыполнения)); 58 | 59 | Возврат ИтоговыйРезультатВыполнения <> ИсполнительБДД.ВозможныеСтатусыВыполнения().Сломался; 60 | КонецФункции // ПрогнатьФичи() 61 | 62 | Попытка 63 | ТестыПрошли = ПрогнатьТесты(); 64 | 65 | Исключение 66 | ТестыПрошли = Ложь; 67 | Сообщить(СтрШаблон("Тесты через 1testrunner выполнены неудачно 68 | |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); 69 | КонецПопытки; 70 | 71 | Попытка 72 | ФичиПрошли = ПрогнатьФичи(); 73 | Исключение 74 | ФичиПрошли = Ложь; 75 | Сообщить(СтрШаблон("Тесты поведения через 1bdd выполнены неудачно 76 | |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); 77 | КонецПопытки; 78 | 79 | Если Не ТестыПрошли Или Не ФичиПрошли Тогда 80 | ВызватьИсключение "Тестирование завершилось неудачно!"; 81 | Иначе 82 | Сообщить(СтрШаблон("Результат прогона тестов <%1> 83 | |", ТестыПрошли)); 84 | КонецЕсли; 85 | -------------------------------------------------------------------------------- /tests/fixtures/appender-debug.os: -------------------------------------------------------------------------------- 1 | Перем мСообщенияЛога; 2 | 3 | Функция ПолучитьСообщения() Экспорт 4 | Возврат мСообщенияЛога; 5 | КонецФункции 6 | 7 | //////////////////////////// 8 | // Методы аппендера 9 | 10 | Процедура Вывести(Знач Сообщение, Знач УровеньВывода) Экспорт 11 | мСообщенияЛога.Добавить(Сообщение); 12 | КонецПроцедуры 13 | 14 | Процедура Закрыть() Экспорт 15 | мСообщенияЛога = Неопределено; 16 | КонецПроцедуры 17 | 18 | мСообщенияЛога = Новый Массив; 19 | -------------------------------------------------------------------------------- /tests/fixtures/v1-layout.os: -------------------------------------------------------------------------------- 1 | Функция Форматировать(Знач Уровень, Знач Сообщение) Экспорт 2 | 3 | Возврат СтрШаблон("%1 - %2", УровниЛога.НаименованиеУровня(Уровень), Сообщение); 4 | 5 | КонецФункции -------------------------------------------------------------------------------- /tests/fixtures/v2-withFields.os: -------------------------------------------------------------------------------- 1 | 2 | Перем мМассивСобытий Экспорт; 3 | Перем РаскладкаСообщения; 4 | 5 | Функция ПолучитьФорматированноеСообщение(Знач СобытиеЛога) Экспорт 6 | 7 | мМассивСобытий.Добавить(СобытиеЛога); 8 | 9 | Возврат РаскладкаСообщения.ПолучитьФорматированноеСообщение(СобытиеЛога); 10 | 11 | КонецФункции 12 | 13 | РаскладкаСообщения = Новый ОсновнаяРаскладкаСообщения(); 14 | 15 | мМассивСобытий = Новый Массив(); -------------------------------------------------------------------------------- /tests/json-layout_test.os: -------------------------------------------------------------------------------- 1 | #использовать ".." 2 | #Использовать asserts 3 | 4 | Перем юТест; 5 | Перем мСообщенияЛога; 6 | Перем Лог; 7 | 8 | Функция ПолучитьСписокТестов(Знач Тестирование) Экспорт 9 | 10 | юТест = Тестирование; 11 | 12 | ИменаТестов = Новый Массив; 13 | 14 | ИменаТестов.Добавить("ТестДолжен_ПроверитьJSONРаскладкуСообщения"); 15 | // ИменаТестов.Добавить("ТестДолжен_ПроверитьУстановкуФорматаДаты"); 16 | 17 | Возврат ИменаТестов; 18 | 19 | КонецФункции 20 | 21 | Процедура ПередЗапускомТеста() Экспорт 22 | 23 | Лог = Логирование.ПолучитьЛог("testing"); 24 | Лог.УстановитьУровень(УровниЛога.Отладка); 25 | 26 | КонецПроцедуры 27 | 28 | Процедура ПослеЗапускаТеста() Экспорт 29 | 30 | Лог.УдалитьСпособВывода(ЭтотОбъект); 31 | Логирование.ЗакрытьЛог(Лог); 32 | Лог = Неопределено; 33 | мСообщенияЛога = Неопределено; 34 | 35 | КонецПроцедуры 36 | 37 | Процедура ТестДолжен_ПроверитьJSONРаскладкуСообщения() Экспорт 38 | 39 | JSONРаскладкаСообщения = Новый JSONРаскладкаСообщения; 40 | ДобавитьСебяКакОбработчикаВывода(); 41 | 42 | Лог.УстановитьРаскладку(JSONРаскладкаСообщения); 43 | Лог.Поля("prefix", "connect", "корова", 200, "адрес", "server.com") 44 | .Ошибка( 45 | "Вывод 46 | | ошибка 47 | | &ЯАмперсанд 48 | | <Я угловые скобки> 49 | | `Я одинарные кавычки` 50 | | \ Я слеши /" 51 | ); 52 | 53 | ДанныеЛога = ПрочитатьJSONЛога(мСообщенияЛога[0]); 54 | 55 | Ожидаем.Что(ДанныеЛога["prefix"]).Равно("connect"); 56 | Ожидаем.Что(ДанныеЛога["корова"]).Равно(200); 57 | Ожидаем.Что(ДанныеЛога["адрес"]).Равно("server.com"); 58 | Ожидаем.Что(ДанныеЛога["msg"]) 59 | .Равно( 60 | "Вывод 61 | | ошибка 62 | | &ЯАмперсанд 63 | | <Я угловые скобки> 64 | | `Я одинарные кавычки` 65 | | \ Я слеши /" 66 | ); 67 | Ожидаем.Что(ДанныеЛога["level"]).Равно("ERROR"); 68 | 69 | КонецПроцедуры 70 | 71 | Процедура ДобавитьСебяКакОбработчикаВывода(Знач НовыйУровень = Неопределено) 72 | 73 | мСообщенияЛога = Новый Массив; 74 | Лог.ДобавитьСпособВывода(ЭтотОбъект, НовыйУровень); 75 | 76 | КонецПроцедуры 77 | 78 | Функция ПрочитатьJSONЛога(Знач СтрокаJSON) 79 | 80 | ЧтениеJSON = Новый ЧтениеJSON(); 81 | ЧтениеJSON.УстановитьСтроку(СтрокаJSON); 82 | 83 | Данные = ПрочитатьJSON(ЧтениеJSON); 84 | 85 | Возврат Данные; 86 | 87 | КонецФункции 88 | 89 | // Выводит событие лога 90 | // 91 | // Параметры: 92 | // СобытиеЛога - Объект - объект класса <СобытиеЛога> 93 | // 94 | Процедура ВывестиСобытие(Знач СобытиеЛога) Экспорт 95 | мСообщенияЛога.Добавить(СобытиеЛога.ПолучитьФорматированноеСообщение()); 96 | КонецПроцедуры 97 | 98 | Процедура Закрыть() Экспорт 99 | мСообщенияЛога = Неопределено; 100 | КонецПроцедуры -------------------------------------------------------------------------------- /tests/logos-test.os: -------------------------------------------------------------------------------- 1 | #Использовать ".." 2 | #Использовать asserts 3 | #Использовать tempfiles 4 | 5 | Перем юТест; 6 | Перем Лог; 7 | 8 | Перем мСообщенияЛога; 9 | Перем ПеремСредыЛогаСохр; 10 | Перем ПеремСредыУровняЛогаСохр; 11 | 12 | Функция ПолучитьСписокТестов(Знач ЮнитТестирование) Экспорт 13 | 14 | юТест = ЮнитТестирование; 15 | 16 | МассивТестов = Новый Массив; 17 | МассивТестов.Добавить("Тест_ДолженСоздатьЛоггерПоУмолчанию"); 18 | МассивТестов.Добавить("Тест_ДолженПроверитьУровниВывода"); 19 | МассивТестов.Добавить("Тест_ДолженПроверитьЧтоЗарегистрированыАппендеры"); 20 | МассивТестов.Добавить("Тест_ДолженПроверитьЧтоУровниВыводаИзменяются"); 21 | МассивТестов.Добавить("Тест_ДолженПроверитьЧтоАппендерУстановлен"); 22 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводБолееПриоритетногоСообщения"); 23 | МассивТестов.Добавить("Тест_ДолженПроверитьЧтоНеВыводятсяМенееПриоритетныеСообщения"); 24 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводОтладки"); 25 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводИнформации"); 26 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводПредупреждения"); 27 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводОшибки"); 28 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводКритичнойОшибки"); 29 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводОтладкиЧерезСтрШаблон"); 30 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводИнформацииЧерезСтрШаблон"); 31 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводПредупрежденияЧерезСтрШаблон"); 32 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводОшибкиЧерезСтрШаблон"); 33 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводКритичнойОшибкиЧерезСтрШаблон"); 34 | МассивТестов.Добавить("Тест_ДолженПроверитьСозданиеИдентификатораВЛоге"); 35 | МассивТестов.Добавить("Тест_ДолженПроверитьЗакрытиеЛогаПоСчетчикуСсылок"); 36 | МассивТестов.Добавить("Тест_ДолженПрочитатьНастройкиЛогированияИзФайла"); 37 | МассивТестов.Добавить("Тест_ДолженПрочитатьНастройкиЛогированияИзПеременнойСреды"); 38 | МассивТестов.Добавить("Тест_ДолженПроверитьЧтоКорневойЛоггерВлияетНаВсеСоздаваемые"); 39 | МассивТестов.Добавить("Тест_ДолженПроверитьЧтоКорневойЛоггерВлияетНаВсеСоздаваемыеПриДругойПеременнойСреды"); 40 | МассивТестов.Добавить("Тест_ДолженПроверитьЧтоКорневойЛоггерВлияетНаВсеСоздаваемыеПриДругойПеременнойСредыПриУровнеОшибка"); 41 | МассивТестов.Добавить("Тест_ДолженПроверитьПриоритетПеременныхСреды"); 42 | МассивТестов.Добавить("Тест_ДолженПроверитьЧтоТочечнаяНастройкаЗаменяетКорневую"); 43 | МассивТестов.Добавить("Тест_ДолженВывестиВЛогПростуюСтрокуБезПараметров"); 44 | МассивТестов.Добавить("Тест_ДолженВывестиВЛогПростуюСтрокуСПустымПараметром"); 45 | МассивТестов.Добавить("Тест_ДолженПроверитьНастройкуРазныхУровнейУРазныхСпособовВывода"); 46 | МассивТестов.Добавить("Тест_ДолженПроверитьНастройкуРазныхУровнейУРазныхСпособовВывода_ИнформацияЗатемОтладка"); 47 | МассивТестов.Добавить("Тест_ДолженПроверитьНастройкуРазныхУровнейУРазныхСпособовВывода_ОтладкаЗатемИнформация"); 48 | МассивТестов.Добавить("Тест_ДолженПроверитьСменуУровняСпособаВыводаПриПереустановкеУровняЛога"); 49 | МассивТестов.Добавить("Тест_ДолженПроверитьДобавлениеИмениЛогаДляУровняОтладка"); 50 | МассивТестов.Добавить("Тест_ДолженПроверитьОтсутствиеСменыЯвноЗаданногоУровняСпособаВыводаПриПереустановкеУровняЛога"); 51 | МассивТестов.Добавить("Тест_ДолженПроверитьСокращениеИмениЛогаПриВыводеСообщения"); 52 | МассивТестов.Добавить("Тест_ДолженПроверитьРаботуРаскладкиСAPIv1"); 53 | МассивТестов.Добавить("Тест_ДолженПроверитьРаботуПередачуДополнительныхПолей"); 54 | МассивТестов.Добавить("Тест_ДолженПроверитьПолучениеСпискаЛоговПоФильтру"); 55 | МассивТестов.Добавить("Тест_ДолженПроверитьВыводДвухЛоговВОДинФайл"); 56 | МассивТестов.Добавить("Тест_ДолженПроверитьПриемственностьИерархииЛогов"); 57 | 58 | Возврат МассивТестов; 59 | 60 | КонецФункции 61 | 62 | Процедура ПередЗапускомТеста() Экспорт 63 | Лог = Логирование.ПолучитьЛог("logos.internal"); 64 | 65 | ПеремСредыЛогаСохр = ПолучитьПеременнуюСреды("LOGOS_CONFIG"); 66 | ПеремСредыУровняЛогаСохр = ПолучитьПеременнуюСреды("LOGOS_LEVEL"); 67 | УстановитьПеременнуюСреды("LOGOS_CONFIG", ""); 68 | УстановитьПеременнуюСреды("LOGOS_LEVEL", ""); 69 | 70 | КонецПроцедуры 71 | 72 | Процедура ПослеЗапускаТеста() Экспорт 73 | Лог.УдалитьСпособВывода(ЭтотОбъект); 74 | Логирование.ЗакрытьЛог(Лог); 75 | Лог = Неопределено; 76 | мСообщенияЛога = Неопределено; 77 | 78 | УстановитьПеременнуюСреды("LOGOS_CONFIG", ПеремСредыЛогаСохр); 79 | УстановитьПеременнуюСреды("LOGOS_LEVEL", ПеремСредыУровняЛогаСохр); 80 | 81 | ВременныеФайлы.Удалить(); 82 | КонецПроцедуры 83 | 84 | Процедура Тест_ДолженСоздатьЛоггерПоУмолчанию() Экспорт 85 | 86 | Утверждения.ПроверитьРавенство(УровниЛога.Информация, Лог.Уровень()); 87 | 88 | КонецПроцедуры 89 | 90 | Процедура Тест_ДолженПроверитьУровниВывода() Экспорт 91 | 92 | Утверждения.ПроверитьРавенство(0, УровниЛога.Отладка); 93 | Утверждения.ПроверитьРавенство(1, УровниЛога.Информация); 94 | Утверждения.ПроверитьРавенство(2, УровниЛога.Предупреждение); 95 | Утверждения.ПроверитьРавенство(3, УровниЛога.Ошибка); 96 | Утверждения.ПроверитьРавенство(4, УровниЛога.КритичнаяОшибка); 97 | Утверждения.ПроверитьРавенство(5, УровниЛога.Отключить); 98 | 99 | КонецПроцедуры 100 | 101 | Процедура Тест_ДолженПроверитьЧтоЗарегистрированыАппендеры() Экспорт 102 | 103 | // данные типы регистрируются при создании логгера 104 | ВФайл = Новый ВыводЛогаВФайл(); 105 | Утверждения.ПроверитьРавенство(Тип("ВыводЛогаВФайл"), ТипЗнч(ВФайл)); 106 | 107 | ВыводЛогаВКонсоль = Новый ВыводЛогаВКонсоль(); 108 | Утверждения.ПроверитьРавенство(Тип("ВыводЛогаВКонсоль"), ТипЗнч(ВыводЛогаВКонсоль)); 109 | 110 | КонецПроцедуры 111 | 112 | Процедура Тест_ДолженПроверитьЧтоУровниВыводаИзменяются() Экспорт 113 | 114 | Утверждения.ПроверитьРавенство(УровниЛога.Информация, Лог.Уровень()); 115 | 116 | Лог.УстановитьУровень(УровниЛога.Предупреждение); 117 | 118 | Утверждения.ПроверитьРавенство(УровниЛога.Предупреждение, Лог.Уровень()); 119 | 120 | КонецПроцедуры 121 | 122 | Процедура Тест_ДолженПроверитьЧтоАппендерУстановлен() Экспорт 123 | ДобавитьСебяКакОбработчикаВывода(); 124 | Лог.Информация("Привет"); 125 | Утверждения.ПроверитьРавенство("ИНФОРМАЦИЯ - " + "Привет", мСообщенияЛога[0]); 126 | КонецПроцедуры 127 | 128 | Процедура Тест_ДолженПроверитьВыводБолееПриоритетногоСообщения() Экспорт 129 | 130 | ДобавитьСебяКакОбработчикаВывода(); 131 | Лог.Информация("Привет"); 132 | Лог.Ошибка("Ошибка"); 133 | Утверждения.ПроверитьРавенство(2, мСообщенияЛога.Количество()); 134 | Ожидаем.Что(мСообщенияЛога[0]).Равно("ИНФОРМАЦИЯ - " + "Привет"); 135 | Ожидаем.Что(мСообщенияЛога[1]).Равно("ОШИБКА - " + "Ошибка"); 136 | 137 | КонецПроцедуры 138 | 139 | Процедура Тест_ДолженПроверитьЧтоНеВыводятсяМенееПриоритетныеСообщения() Экспорт 140 | 141 | ДобавитьСебяКакОбработчикаВывода(); 142 | Лог.УстановитьУровень(УровниЛога.Ошибка); 143 | Лог.Информация("Привет"); 144 | Лог.Ошибка("Ошибка"); 145 | Утверждения.ПроверитьРавенство(1, мСообщенияЛога.Количество()); 146 | Утверждения.ПроверитьРавенство("ОШИБКА - " + "Ошибка", мСообщенияЛога[0]); 147 | 148 | КонецПроцедуры 149 | 150 | Процедура Тест_ДолженПроверитьВыводОтладки() Экспорт 151 | 152 | Лог.УстановитьУровень(УровниЛога.Отладка); 153 | ДобавитьСебяКакОбработчикаВывода(); 154 | Лог.Отладка("Привет"); 155 | Утверждения.ПроверитьРавенство("ОТЛАДКА - [logos.internal] - " + "Привет", мСообщенияЛога[0]); 156 | 157 | КонецПроцедуры 158 | 159 | Процедура Тест_ДолженПроверитьВыводИнформации() Экспорт 160 | 161 | ДобавитьСебяКакОбработчикаВывода(); 162 | Лог.УстановитьУровень(УровниЛога.Информация); 163 | Лог.Информация("Привет"); 164 | Утверждения.ПроверитьРавенство("ИНФОРМАЦИЯ - " + "Привет", мСообщенияЛога[0]); 165 | 166 | КонецПроцедуры 167 | 168 | Процедура Тест_ДолженПроверитьВыводПредупреждения() Экспорт 169 | 170 | ДобавитьСебяКакОбработчикаВывода(); 171 | Лог.УстановитьУровень(УровниЛога.Предупреждение); 172 | Лог.Предупреждение("Привет"); 173 | Утверждения.ПроверитьРавенство("ПРЕДУПРЕЖДЕНИЕ - " + "Привет", мСообщенияЛога[0]); 174 | 175 | КонецПроцедуры 176 | 177 | Процедура Тест_ДолженПроверитьВыводОшибки() Экспорт 178 | 179 | ДобавитьСебяКакОбработчикаВывода(); 180 | Лог.УстановитьУровень(УровниЛога.Ошибка); 181 | Лог.Ошибка("Привет"); 182 | Утверждения.ПроверитьРавенство("ОШИБКА - " + "Привет", мСообщенияЛога[0]); 183 | 184 | КонецПроцедуры 185 | 186 | Процедура Тест_ДолженПроверитьВыводКритичнойОшибки() Экспорт 187 | 188 | ДобавитьСебяКакОбработчикаВывода(); 189 | Лог.УстановитьУровень(УровниЛога.КритичнаяОшибка); 190 | Лог.КритичнаяОшибка("Привет"); 191 | Утверждения.ПроверитьРавенство("КРИТИЧНАЯОШИБКА - " + "Привет", мСообщенияЛога[0]); 192 | 193 | КонецПроцедуры 194 | 195 | Процедура Тест_ДолженПроверитьВыводОтладкиЧерезСтрШаблон() Экспорт 196 | 197 | Лог.УстановитьУровень(УровниЛога.Отладка); 198 | ДобавитьСебяКакОбработчикаВывода(); 199 | Лог.Отладка("Привет %1,%2", "Первый", "Второй"); 200 | Утверждения.ПроверитьРавенство("ОТЛАДКА - [logos.internal] - " + "Привет Первый,Второй", мСообщенияЛога[0]); 201 | 202 | КонецПроцедуры 203 | 204 | Процедура Тест_ДолженПроверитьВыводИнформацииЧерезСтрШаблон() Экспорт 205 | 206 | ДобавитьСебяКакОбработчикаВывода(); 207 | Лог.УстановитьУровень(УровниЛога.Информация); 208 | Лог.Информация("Привет %1,%2", "Первый", "Второй"); 209 | Утверждения.ПроверитьРавенство("ИНФОРМАЦИЯ - " + "Привет Первый,Второй", мСообщенияЛога[0]); 210 | 211 | КонецПроцедуры 212 | 213 | Процедура Тест_ДолженПроверитьВыводПредупрежденияЧерезСтрШаблон() Экспорт 214 | 215 | ДобавитьСебяКакОбработчикаВывода(); 216 | Лог.УстановитьУровень(УровниЛога.Предупреждение); 217 | Лог.Предупреждение("Привет %1,%2", "Первый", "Второй"); 218 | Утверждения.ПроверитьРавенство("ПРЕДУПРЕЖДЕНИЕ - " + "Привет Первый,Второй", мСообщенияЛога[0]); 219 | 220 | КонецПроцедуры 221 | 222 | Процедура Тест_ДолженПроверитьВыводОшибкиЧерезСтрШаблон() Экспорт 223 | 224 | ДобавитьСебяКакОбработчикаВывода(); 225 | Лог.УстановитьУровень(УровниЛога.Ошибка); 226 | Лог.Ошибка("Привет %1,%2", "Первый", "Второй"); 227 | Утверждения.ПроверитьРавенство("ОШИБКА - " + "Привет Первый,Второй", мСообщенияЛога[0]); 228 | 229 | КонецПроцедуры 230 | 231 | Процедура Тест_ДолженПроверитьВыводКритичнойОшибкиЧерезСтрШаблон() Экспорт 232 | 233 | ДобавитьСебяКакОбработчикаВывода(); 234 | Лог.УстановитьУровень(УровниЛога.КритичнаяОшибка); 235 | Лог.КритичнаяОшибка("Привет %1,%2", "Первый", "Второй"); 236 | Утверждения.ПроверитьРавенство("КРИТИЧНАЯОШИБКА - " + "Привет Первый,Второй", мСообщенияЛога[0]); 237 | 238 | КонецПроцедуры 239 | 240 | Процедура Тест_ДолженВывестиВЛогПростуюСтрокуБезПараметров() Экспорт 241 | 242 | ДобавитьСебяКакОбработчикаВывода(); 243 | Лог.УстановитьУровень(УровниЛога.Информация); 244 | Лог.Информация("Привет"); 245 | Утверждения.ПроверитьРавенство("ИНФОРМАЦИЯ - Привет", мСообщенияЛога[0]); 246 | 247 | КонецПроцедуры 248 | 249 | Процедура Тест_ДолженВывестиВЛогПростуюСтрокуСПустымПараметром() Экспорт 250 | 251 | ДобавитьСебяКакОбработчикаВывода(); 252 | Лог.УстановитьУровень(УровниЛога.Информация); 253 | Лог.Информация("Привет <%1>", Неопределено); 254 | Утверждения.ПроверитьРавенство("ИНФОРМАЦИЯ - Привет <%1>", мСообщенияЛога[0]); 255 | 256 | КонецПроцедуры 257 | 258 | Процедура ДобавитьСебяКакОбработчикаВывода(Знач НовыйУровень = Неопределено) 259 | 260 | мСообщенияЛога = Новый Массив; 261 | Лог.ДобавитьСпособВывода(ЭтотОбъект, НовыйУровень); 262 | 263 | КонецПроцедуры 264 | 265 | Процедура Тест_ДолженПроверитьСозданиеИдентификатораВЛоге() Экспорт 266 | 267 | ИД = Лог.ПолучитьИдентификатор(); 268 | Утверждения.Проверить(ЗначениеЗаполнено(ИД)); 269 | 270 | КонецПроцедуры 271 | 272 | Процедура Тест_ДолженПроверитьЗакрытиеЛогаПоСчетчикуСсылок() Экспорт 273 | ДобавитьСебяКакОбработчикаВывода(); 274 | Лог2 = Логирование.ПолучитьЛог("logos.internal"); 275 | Лог2.Информация("ТестовоеСообщение"); 276 | Утверждения.ПроверитьРавенство(1, мСообщенияЛога.Количество()); 277 | Утверждения.ПроверитьРавенство(Лог, Лог2); 278 | Логирование.ЗакрытьЛог(Лог); // закрываем в неправильном порядке, но sink должен остаться открыт 279 | Утверждения.ПроверитьРавенство(1, мСообщенияЛога.Количество()); 280 | Логирование.ЗакрытьЛог(Лог2); 281 | Утверждения.ПроверитьРавенство(Неопределено, мСообщенияЛога); 282 | КонецПроцедуры 283 | 284 | Процедура Тест_ДолженПрочитатьНастройкиЛогированияИзФайла() Экспорт 285 | 286 | ФайлНастроек = ВременныеФайлы.НовоеИмяФайла("cfg"); 287 | ЗаписьТекста = Новый ЗаписьТекста(ФайлНастроек); 288 | 289 | ЗаписьТекста.ЗаписатьСтроку("logger.errlog=ERROR"); // простая установка уровня 290 | ЗаписьТекста.ЗаписатьСтроку("logger.debuglog=DEBUG, debugfile"); // уровень + аппендер 291 | ЗаписьТекста.ЗаписатьСтроку("appender.debugfile=ВыводЛогаВФайл"); // класс аппендера 292 | ЗаписьТекста.ЗаписатьСтроку("appender.debugfile.level=WARN"); // свойство аппендера 293 | ЗаписьТекста.ЗаписатьСтроку("appender.debugfile.file=/tmp/logostestdebug"); // свойство аппендера 294 | ЗаписьТекста.ЗаписатьСтроку("appender.debugfile.anotherprop=hello world"); // свойство аппендера 295 | ЗаписьТекста.Закрыть(); 296 | 297 | Настройки = Новый НастройкиЛогирования(); 298 | Настройки.Прочитать(ФайлНастроек); 299 | 300 | НастройкиЛогаОшибок = Настройки.Получить("errlog"); 301 | Ожидаем.Что(НастройкиЛогаОшибок.Уровень).Равно(УровниЛога.Ошибка); 302 | Ожидаем.Что(НастройкиЛогаОшибок.СпособыВывода).ИмеетДлину(0); 303 | 304 | НастройкиЛогаОтладки = Настройки.Получить("debuglog"); 305 | Ожидаем.Что(НастройкиЛогаОтладки.Уровень).Равно(УровниЛога.Отладка); 306 | Ожидаем.Что(НастройкиЛогаОтладки.СпособыВывода).ИмеетДлину(1); 307 | 308 | ОписаниеАппендера = НастройкиЛогаОтладки.СпособыВывода["debugfile"]; 309 | Ожидаем.Что(ОписаниеАппендера.Класс).Равно("ВыводЛогаВФайл"); 310 | Ожидаем.Что(ОписаниеАппендера.Уровень).Равно(УровниЛога.Предупреждение); 311 | Ожидаем.Что(ОписаниеАппендера.Свойства["file"]).Равно("/tmp/logostestdebug"); 312 | Ожидаем.Что(ОписаниеАппендера.Свойства["anotherprop"]).Равно("hello world"); 313 | 314 | КонецПроцедуры 315 | 316 | Процедура Тест_ДолженПрочитатьНастройкиЛогированияИзПеременнойСреды() Экспорт 317 | 318 | УстановитьПеременнуюСреды("LOGOS_CONFIG", "logger.errlog=ERROR;logger.debuglog=DEBUG, debugfile;appender.debugfile=ВыводЛогаВФайл;appender.debugfile.level=WARN;appender.debugfile.file=/tmp/logostestdebug;appender.debugfile.anotherprop=hello world"); 319 | Логирование.ОбновитьНастройки(); 320 | 321 | КонфигИзСреды = ПолучитьПеременнуюСреды("LOGOS_CONFIG"); 322 | 323 | Настройки = Новый НастройкиЛогирования(); 324 | 325 | КонфигИзСреды = СтрЗаменить(КонфигИзСреды, ";", Символы.ПС); 326 | Настройки.ПрочитатьИзСтроки(КонфигИзСреды); 327 | 328 | НастройкиЛогаОшибок = Настройки.Получить("errlog"); 329 | Ожидаем.Что(НастройкиЛогаОшибок.Уровень).Равно(УровниЛога.Ошибка); 330 | Ожидаем.Что(НастройкиЛогаОшибок.СпособыВывода).ИмеетДлину(0); 331 | 332 | НастройкиЛогаОтладки = Настройки.Получить("debuglog"); 333 | Ожидаем.Что(НастройкиЛогаОтладки.Уровень).Равно(УровниЛога.Отладка); 334 | Ожидаем.Что(НастройкиЛогаОтладки.СпособыВывода).ИмеетДлину(1); 335 | 336 | ОписаниеАппендера = НастройкиЛогаОтладки.СпособыВывода["debugfile"]; 337 | Ожидаем.Что(ОписаниеАппендера.Класс).Равно("ВыводЛогаВФайл"); 338 | Ожидаем.Что(ОписаниеАппендера.Уровень).Равно(УровниЛога.Предупреждение); 339 | Ожидаем.Что(ОписаниеАппендера.Свойства["file"]).Равно("/tmp/logostestdebug"); 340 | Ожидаем.Что(ОписаниеАппендера.Свойства["anotherprop"]).Равно("hello world"); 341 | 342 | КонецПроцедуры 343 | 344 | Процедура Тест_ДолженПроверитьЧтоКорневойЛоггерВлияетНаВсеСоздаваемые() Экспорт 345 | 346 | УстановитьПеременнуюСреды("LOGOS_CONFIG", "logger.rootLogger=DEBUG"); 347 | Логирование.ОбновитьНастройки(); 348 | 349 | Лог = Логирование.ПолучитьЛог("testlog"); 350 | Ожидаем.Что(Лог.Уровень()).Равно(УровниЛога.Отладка); 351 | 352 | КонецПроцедуры 353 | 354 | Процедура Тест_ДолженПроверитьЧтоКорневойЛоггерВлияетНаВсеСоздаваемыеПриДругойПеременнойСреды() Экспорт 355 | 356 | УстановитьПеременнуюСреды("LOGOS_LEVEL", "DEBUG"); 357 | Логирование.ОбновитьНастройки(); 358 | 359 | Лог = Логирование.ПолучитьЛог("testlog"); 360 | Ожидаем.Что(Лог.Уровень(), "Лог.Уровень Равно Отладка").Равно(УровниЛога.Отладка); 361 | 362 | КонецПроцедуры 363 | 364 | Процедура Тест_ДолженПроверитьЧтоКорневойЛоггерВлияетНаВсеСоздаваемыеПриДругойПеременнойСредыПриУровнеОшибка() Экспорт 365 | 366 | УстановитьПеременнуюСреды("LOGOS_LEVEL", "ERROR"); 367 | Логирование.ОбновитьНастройки(); 368 | 369 | Лог = Логирование.ПолучитьЛог("testlog"); 370 | Ожидаем.Что(Лог.Уровень(), "Лог.Уровень Равно Ошибка").Равно(УровниЛога.Ошибка); 371 | 372 | КонецПроцедуры 373 | 374 | Процедура Тест_ДолженПроверитьПриоритетПеременныхСреды() Экспорт 375 | 376 | УстановитьПеременнуюСреды("LOGOS_LEVEL", "ERROR"); 377 | УстановитьПеременнуюСреды("LOGOS_CONFIG", "logger.rootLogger=DEBUG"); 378 | Логирование.ОбновитьНастройки(); 379 | 380 | Лог = Логирование.ПолучитьЛог("testlog"); 381 | Ожидаем.Что(Лог.Уровень(), "Лог.Уровень Равно Отладка").Равно(УровниЛога.Отладка); 382 | 383 | КонецПроцедуры 384 | 385 | Процедура Тест_ДолженПроверитьЧтоТочечнаяНастройкаЗаменяетКорневую() Экспорт 386 | 387 | УстановитьПеременнуюСреды("LOGOS_CONFIG", "logger.rootLogger=DEBUG;logger.specificLogger=WARN"); 388 | Логирование.ОбновитьНастройки(); 389 | 390 | Лог = Логирование.ПолучитьЛог("testlog"); 391 | Ожидаем.Что(Лог.Уровень(), "Должна сработать корневая настройка").Равно(УровниЛога.Отладка); 392 | Лог = Логирование.ПолучитьЛог("specificLogger"); 393 | Ожидаем.Что(Лог.Уровень(), "Должна сработать специализированная настройка").Равно(УровниЛога.Предупреждение); 394 | 395 | КонецПроцедуры 396 | 397 | Процедура Тест_ДолженПроверитьНастройкуРазныхУровнейУРазныхСпособовВывода() Экспорт 398 | Лог = Логирование.ПолучитьЛог("testlog"); 399 | Лог.УстановитьУровень(УровниЛога.Информация); 400 | 401 | ДобавитьСебяКакОбработчикаВывода(); 402 | 403 | Ожидаем.Что(Лог.УровеньСпособаВывода(ЭтотОбъект), "УровеньСпособаВывода(ЭтотОбъект)").Равно(УровниЛога.Информация); 404 | 405 | ВторойСпособВывода = ЗагрузитьСценарий(ОбъединитьПути(ПутьКТестам(), "fixtures", "appender-debug.os")); 406 | 407 | Лог.ДобавитьСпособВывода(ВторойСпособВывода, УровниЛога.ПРЕДУПРЕЖДЕНИЕ); 408 | Ожидаем.Что(Лог.УровеньСпособаВывода(ВторойСпособВывода), "УровеньСпособаВывода(ВторойСпособВывода)").Равно(УровниЛога.ПРЕДУПРЕЖДЕНИЕ); 409 | 410 | Лог.Информация("Привет"); 411 | Лог.Предупреждение("Внимание"); 412 | Лог.Отладка("Отладка включена"); 413 | 414 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(2); 415 | Ожидаем.Что(мСообщенияЛога[0], "мСообщенияЛога[0]").Равно("ИНФОРМАЦИЯ - "+"Привет"); 416 | Ожидаем.Что(мСообщенияЛога[1], "мСообщенияЛога[1]").Равно("ПРЕДУПРЕЖДЕНИЕ - "+"Внимание"); 417 | 418 | Сообщения2 = ВторойСпособВывода.ПолучитьСообщения(); 419 | Ожидаем.Что(Сообщения2, "Сообщения2").ИмеетДлину(1); 420 | Ожидаем.Что(Сообщения2[0], "ВторойСпособВывода 0").Равно("ПРЕДУПРЕЖДЕНИЕ - "+"Внимание"); 421 | КонецПроцедуры 422 | 423 | Процедура Тест_ДолженПроверитьНастройкуРазныхУровнейУРазныхСпособовВывода_ИнформацияЗатемОтладка() Экспорт 424 | Лог = Логирование.ПолучитьЛог("testlog"); 425 | Лог.УстановитьУровень(УровниЛога.Информация); 426 | 427 | ДобавитьСебяКакОбработчикаВывода(); 428 | 429 | Ожидаем.Что(Лог.УровеньСпособаВывода(ЭтотОбъект), "УровеньСпособаВывода(ЭтотОбъект)").Равно(УровниЛога.Информация); 430 | 431 | ВторойСпособВывода = ЗагрузитьСценарий(ОбъединитьПути(ПутьКТестам(), "fixtures", "appender-debug.os")); 432 | 433 | Лог.ДобавитьСпособВывода(ВторойСпособВывода, УровниЛога.Отладка); 434 | Ожидаем.Что(Лог.УровеньСпособаВывода(ВторойСпособВывода), "УровеньСпособаВывода(ВторойСпособВывода)").Равно(УровниЛога.Отладка); 435 | 436 | Лог.Информация("Привет"); 437 | Лог.Предупреждение("Внимание"); 438 | Лог.Отладка("Отладка включена"); 439 | 440 | Ожидаем.Что(мСообщенияЛога[0], "мСообщенияЛога[0]").Равно("ИНФОРМАЦИЯ - "+"Привет"); 441 | Ожидаем.Что(мСообщенияЛога[1], "мСообщенияЛога[1]").Равно("ПРЕДУПРЕЖДЕНИЕ - "+"Внимание"); 442 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(2); 443 | 444 | Сообщения2 = ВторойСпособВывода.ПолучитьСообщения(); 445 | Ожидаем.Что(Сообщения2[0], "ВторойСпособВывода 0").Равно("ИНФОРМАЦИЯ - "+"Привет"); 446 | Ожидаем.Что(Сообщения2[1], "ВторойСпособВывода 1").Равно("ПРЕДУПРЕЖДЕНИЕ - "+"Внимание"); 447 | Ожидаем.Что(Сообщения2[2], "ВторойСпособВывода 2").Равно("ОТЛАДКА - "+"Отладка включена"); 448 | Ожидаем.Что(Сообщения2, "Сообщения2").ИмеетДлину(3); 449 | КонецПроцедуры 450 | 451 | Процедура Тест_ДолженПроверитьНастройкуРазныхУровнейУРазныхСпособовВывода_ОтладкаЗатемИнформация() Экспорт 452 | Лог = Логирование.ПолучитьЛог("testlog"); 453 | Лог.УстановитьУровень(УровниЛога.Информация); 454 | 455 | ПутьФайла = ОбъединитьПути(ПутьКТестам(), "fixtures", "appender-debug.os"); 456 | ПервыйСпособВывода = ЗагрузитьСценарий(ПутьФайла); 457 | ВторойСпособВывода = ЗагрузитьСценарий(ПутьФайла); 458 | 459 | Лог.ДобавитьСпособВывода(ПервыйСпособВывода, УровниЛога.Отладка); 460 | Ожидаем.Что(Лог.УровеньСпособаВывода(ПервыйСпособВывода), "УровеньСпособаВывода(ПервыйСпособВывода)").Равно(УровниЛога.Отладка); 461 | 462 | Лог.ДобавитьСпособВывода(ВторойСпособВывода, УровниЛога.Информация); 463 | Ожидаем.Что(Лог.УровеньСпособаВывода(ВторойСпособВывода), "УровеньСпособаВывода(ВторойСпособВывода)").Равно(УровниЛога.Информация); 464 | 465 | Лог.Информация("Привет"); 466 | Лог.Предупреждение("Внимание"); 467 | Лог.Отладка("Отладка включена"); 468 | 469 | Сообщения1 = ПервыйСпособВывода.ПолучитьСообщения(); 470 | Ожидаем.Что(Сообщения1[0], "ПервыйСпособВывода 0").Равно("ИНФОРМАЦИЯ - "+"Привет"); 471 | Ожидаем.Что(Сообщения1[1], "ПервыйСпособВывода 1").Равно("ПРЕДУПРЕЖДЕНИЕ - "+"Внимание"); 472 | Ожидаем.Что(Сообщения1[2], "ПервыйСпособВывода 2").Равно("ОТЛАДКА - "+"Отладка включена"); 473 | Ожидаем.Что(Сообщения1, "Сообщения1").ИмеетДлину(3); 474 | 475 | Сообщения2 = ВторойСпособВывода.ПолучитьСообщения(); 476 | Ожидаем.Что(Сообщения2[0], "ВторойСпособВывода 0").Равно("ИНФОРМАЦИЯ - "+"Привет"); 477 | Ожидаем.Что(Сообщения2[1], "ВторойСпособВывода 1").Равно("ПРЕДУПРЕЖДЕНИЕ - "+"Внимание"); 478 | Ожидаем.Что(Сообщения2, "Сообщения2").ИмеетДлину(2); 479 | КонецПроцедуры 480 | 481 | Процедура Тест_ДолженПроверитьСменуУровняСпособаВыводаПриПереустановкеУровняЛога() Экспорт 482 | Лог = Логирование.ПолучитьЛог("testlog"); 483 | Лог.УстановитьУровень(УровниЛога.Информация); 484 | 485 | ДобавитьСебяКакОбработчикаВывода(); 486 | 487 | Ожидаем.Что(Лог.УровеньСпособаВывода(ЭтотОбъект), "УровеньСпособаВывода(ЭтотОбъект)").Равно(УровниЛога.Информация); 488 | 489 | Лог.УстановитьУровень(УровниЛога.Отладка); 490 | 491 | Лог.Информация("Привет"); 492 | Лог.Предупреждение("Внимание"); 493 | Лог.Отладка("Отладка включена"); 494 | 495 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(3); 496 | Ожидаем.Что(мСообщенияЛога[0], "мСообщенияЛога[0]").Равно("ИНФОРМАЦИЯ - [testlog] - " + "Привет"); 497 | Ожидаем.Что(мСообщенияЛога[1], "мСообщенияЛога[1]").Равно("ПРЕДУПРЕЖДЕНИЕ - [testlog] - " + "Внимание"); 498 | Ожидаем.Что(мСообщенияЛога[2], "мСообщенияЛога[2]").Равно("ОТЛАДКА - [testlog] - "+"Отладка включена"); 499 | КонецПроцедуры 500 | 501 | Процедура Тест_ДолженПроверитьДобавлениеИмениЛогаДляУровняОтладка() Экспорт 502 | Лог = Логирование.ПолучитьЛог("testlog"); 503 | Лог.УстановитьУровень(УровниЛога.Информация); 504 | 505 | ДобавитьСебяКакОбработчикаВывода(); 506 | 507 | Ожидаем.Что(Лог.УровеньСпособаВывода(ЭтотОбъект), "УровеньСпособаВывода(ЭтотОбъект)").Равно(УровниЛога.Информация); 508 | 509 | Лог.Информация("Привет"); 510 | 511 | Лог.УстановитьУровень(УровниЛога.Отладка); 512 | 513 | Лог.Информация("Привет2"); 514 | 515 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(2); 516 | Ожидаем.Что(мСообщенияЛога[0], "мСообщенияЛога[0]").Равно("ИНФОРМАЦИЯ - " + "Привет"); 517 | Ожидаем.Что(мСообщенияЛога[1], "мСообщенияЛога[1]").Равно("ИНФОРМАЦИЯ - [testlog] - " + "Привет2"); 518 | 519 | КонецПроцедуры 520 | 521 | Процедура Тест_ДолженПроверитьОтсутствиеСменыЯвноЗаданногоУровняСпособаВыводаПриПереустановкеУровняЛога() Экспорт 522 | Лог = Логирование.ПолучитьЛог("testlog"); 523 | Лог.УстановитьУровень(УровниЛога.Информация); 524 | 525 | ДобавитьСебяКакОбработчикаВывода(УровниЛога.Информация); 526 | 527 | Ожидаем.Что(Лог.УровеньСпособаВывода(ЭтотОбъект), "УровеньСпособаВывода(ЭтотОбъект)").Равно(УровниЛога.Информация); 528 | 529 | Лог.УстановитьУровень(УровниЛога.Отладка); 530 | 531 | Лог.Информация("Привет"); 532 | Лог.Предупреждение("Внимание"); 533 | Лог.Отладка("Отладка включена"); 534 | 535 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(2); 536 | Ожидаем.Что(мСообщенияЛога[0], "мСообщенияЛога[0]").Равно("ИНФОРМАЦИЯ - [testlog] - " + "Привет"); 537 | Ожидаем.Что(мСообщенияЛога[1], "мСообщенияЛога[1]").Равно("ПРЕДУПРЕЖДЕНИЕ - [testlog] - " + "Внимание"); 538 | КонецПроцедуры 539 | 540 | Процедура Тест_ДолженПроверитьСокращениеИмениЛогаПриВыводеСообщения() Экспорт 541 | 542 | мСообщенияЛога = Новый Массив; 543 | 544 | ИменаЛогов = Новый Соответствие; 545 | ИменаЛогов.Вставить("testlog", "testlog"); 546 | ИменаЛогов.Вставить("oscript.lib.fakelog", "oscript.lib.fakelog"); 547 | ИменаЛогов.Вставить("oscripttwentysymbols", "oscripttwentysymbols"); 548 | ИменаЛогов.Вставить("oscript.lib.fake.long.path", "o.lib.fake.long.path"); 549 | ИменаЛогов.Вставить("oscript.lib.fake.very.very.very.long.path", "o.l.f.v.v.v.l.path"); 550 | ИменаЛогов.Вставить("oscript.lib.fake.very.very.very.very.very.very.very.very.long.path", "o.l.f.v.v.v.v.v.v.v.v.l.~h"); 551 | ИменаЛогов.Вставить("oscript.lib.fake.longpathinonenode", "o.l.f.~pathinonenode"); 552 | ИменаЛогов.Вставить("oscript.lib.fake.veryveryveryverylongpathinonenode", "o.l.f.~pathinonenode"); 553 | 554 | сч = 0; 555 | Для Каждого ДанныеЛога Из ИменаЛогов Цикл 556 | 557 | // given 558 | Лог = Логирование.ПолучитьЛог(ДанныеЛога.Ключ); 559 | Лог.УстановитьУровень(УровниЛога.Отладка); 560 | 561 | Лог.ДобавитьСпособВывода(ЭтотОбъект, УровниЛога.Отладка); 562 | 563 | // when 564 | Лог.Отладка("Привет"); 565 | 566 | // then 567 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(сч + 1); 568 | ОжидаемаяСтрока = СтрШаблон("ОТЛАДКА - [%1] - Привет", ДанныеЛога.Значение); 569 | Ожидаем.Что(мСообщенияЛога[сч], СтрШаблон("мСообщенияЛога[%1]", сч)).Равно(ОжидаемаяСтрока); 570 | 571 | сч = сч + 1; 572 | 573 | КонецЦикла; 574 | 575 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(ИменаЛогов.Количество()); 576 | 577 | // Закрытие логов 578 | Для Каждого ДанныеЛога Из ИменаЛогов Цикл 579 | Лог = Логирование.ПолучитьЛог(ДанныеЛога.Ключ); 580 | 581 | Лог.УдалитьСпособВывода(ЭтотОбъект); 582 | Логирование.ЗакрытьЛог(Лог); 583 | КонецЦикла; 584 | 585 | КонецПроцедуры 586 | 587 | Процедура Тест_ДолженПроверитьРаботуПередачуДополнительныхПолей() Экспорт 588 | 589 | Лог = Логирование.ПолучитьЛог("testlog"); 590 | Лог.УстановитьУровень(УровниЛога.Информация); 591 | ДобавитьСебяКакОбработчикаВывода(УровниЛога.Информация); 592 | 593 | РаскладкаСПолями = ЗагрузитьСценарий(ОбъединитьПути(ПутьКТестам(), "fixtures", "v2-withFields.os")); 594 | Лог.УстановитьРаскладку(РаскладкаСПолями); 595 | 596 | ПолеДатаВремя = ТекущаяДата(); 597 | 598 | Лог.Поля("ДатаВремя", ПолеДатаВремя, "ПростоПоле", "ПростоПоле").Информация("Привет"); 599 | 600 | Лог.ПоляИз(Новый Структура("ДопПоле, ДопПоле2", "ДопПоле", "ДопПоле2")).Информация("Еще одно сообщение"); 601 | 602 | МассивСобытий = РаскладкаСПолями.мМассивСобытий; 603 | 604 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(2); 605 | Ожидаем.Что(МассивСобытий[0].ПолучитьСообщение(), "МассивСобытий[0].ПолучитьСообщение()").Равно("Привет"); 606 | Ожидаем.Что(МассивСобытий[0].ПолучитьДополнительныеПоля().Получить("ДатаВремя"), "МассивСобытий[0].ПолучитьДополнительныеПоля().Получить(""ДатаВремя"")").Равно(ПолеДатаВремя); 607 | Ожидаем.Что(МассивСобытий[0].ПолучитьДополнительныеПоля().Получить("ПростоПоле"), "МассивСобытий[0].ПолучитьДополнительныеПоля().Получить(""ПростоПоле"")").Равно("ПростоПоле"); 608 | Ожидаем.Что(МассивСобытий[1].ПолучитьСообщение(), "МассивСобытий[1].ПолучитьСообщение()").Равно("Еще одно сообщение"); 609 | Ожидаем.Что(МассивСобытий[1].ПолучитьДополнительныеПоля().Получить("ДопПоле"), "МассивСобытий[1].ПолучитьДополнительныеПоля().Получить(""ДопПоле"")").Равно("ДопПоле"); 610 | Ожидаем.Что(МассивСобытий[1].ПолучитьДополнительныеПоля().Получить("ДопПоле2"), "МассивСобытий[1].ПолучитьДополнительныеПоля().Получить(""ДопПоле2"")").Равно("ДопПоле2"); 611 | 612 | КонецПроцедуры 613 | 614 | Процедура Тест_ДолженПроверитьРаботуПередачуВложенныхДополнительныхПолей() Экспорт 615 | 616 | Лог = Логирование.ПолучитьЛог("testlog"); 617 | Лог.УстановитьУровень(УровниЛога.Информация); 618 | ДобавитьСебяКакОбработчикаВывода(УровниЛога.Информация); 619 | 620 | РаскладкаСПолями = ЗагрузитьСценарий(ОбъединитьПути(ПутьКТестам(), "fixtures", "v2-withFields.os")); 621 | Лог.УстановитьРаскладку(РаскладкаСПолями); 622 | 623 | ПолеДатаВремя = ТекущаяДата(); 624 | 625 | ЛоггерСПолями = Лог.ПоляИз(Новый Структура("ДопПоле, ДопПоле2", "ДопПоле", "ДопПоле2")); 626 | ЛоггерСПолями.Поля("ДатаВремя", ПолеДатаВремя, "ПростоПоле", "ПростоПоле").Информация("Привет"); 627 | 628 | МассивСобытий = РаскладкаСПолями.мМассивСобытий; 629 | 630 | БазоваяСтрока = СтрШаблон("ИНФОРМАЦИЯ - Привет ДопПоле=ДопПоле ДопПоле2=ДопПоле2 ДатаВремя=%1 ПростоПоле=ПростоПоле", ПолеДатаВремя); 631 | 632 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(1); 633 | Ожидаем.Что(МассивСобытий[0].ПолучитьСообщение(), "МассивСобытий[0].ПолучитьСообщение()").Равно("Привет"); 634 | Ожидаем.Что(МассивСобытий[0].ПолучитьДополнительныеПоля().Получить("ДатаВремя"), "МассивСобытий[0].ПолучитьДополнительныеПоля().Получить(""ДатаВремя"")").Равно(ПолеДатаВремя); 635 | Ожидаем.Что(МассивСобытий[0].ПолучитьДополнительныеПоля().Получить("ПростоПоле"), "МассивСобытий[0].ПолучитьДополнительныеПоля().Получить(""ПростоПоле"")").Равно("ПростоПоле"); 636 | Ожидаем.Что(МассивСобытий[0].ПолучитьДополнительныеПоля().Получить("ДопПоле"), "МассивСобытий[0].ПолучитьДополнительныеПоля().Получить(""ДопПоле"")").Равно("ДопПоле"); 637 | Ожидаем.Что(МассивСобытий[0].ПолучитьДополнительныеПоля().Получить("ДопПоле2"), "МассивСобытий[0].ПолучитьДополнительныеПоля().Получить(""ДопПоле2"")").Равно("ДопПоле2"); 638 | 639 | Ожидаем.Что(мСообщенияЛога[0], "мСообщенияЛога[0]").Равно(БазоваяСтрока); 640 | 641 | КонецПроцедуры 642 | 643 | Процедура Тест_ДолженПроверитьПолучениеСпискаЛоговПоФильтру() Экспорт 644 | 645 | Логирование.ПолучитьЛог("oscript.lib.arch"); 646 | Логирование.ПолучитьЛог("oscript.lib.arch.core"); 647 | Логирование.ПолучитьЛог("oscript.lib.arch.parse"); 648 | Логирование.ПолучитьЛог("oscript.lib.arch.logger.file"); 649 | 650 | МассивЛогов = Логирование.СписокСозданныхЛогов("oscript.lib.arch"); 651 | 652 | Ожидаем.Что(МассивЛогов).ИмеетДлину(4); 653 | 654 | КонецПроцедуры 655 | 656 | Процедура Тест_ДолженПроверитьРаботуРаскладкиСAPIv1() Экспорт 657 | Лог = Логирование.ПолучитьЛог("testlog"); 658 | Лог.УстановитьУровень(УровниЛога.Информация); 659 | 660 | РаскладкаAPIv1 = ЗагрузитьСценарий(ОбъединитьПути(ПутьКТестам(), "fixtures", "v1-layout.os")); 661 | Лог.УстановитьРаскладку(РаскладкаAPIv1); 662 | 663 | ДобавитьСебяКакОбработчикаВывода(УровниЛога.Информация); 664 | 665 | Лог.Информация("Привет"); 666 | Лог.Предупреждение("Внимание"); 667 | 668 | Ожидаем.Что(мСообщенияЛога).ИмеетДлину(2); 669 | Ожидаем.Что(мСообщенияЛога[0], "мСообщенияЛога[0]").Равно("ИНФОРМАЦИЯ - " + "Привет"); 670 | Ожидаем.Что(мСообщенияЛога[1], "мСообщенияЛога[1]").Равно("ПРЕДУПРЕЖДЕНИЕ - " + "Внимание"); 671 | КонецПроцедуры 672 | 673 | Процедура Тест_ДолженПроверитьВыводДвухЛоговВОДинФайл() Экспорт 674 | 675 | // Дано 676 | 677 | ФайлЛога = ВременныеФайлы.НовоеИмяФайла("log"); 678 | 679 | ЗначениеПеременнойСреды = СтрШаблон("logger.log1=DEBUG, dbgfile;logger.log2=DEBUG, dbgfile;appender.dbgfile=ВыводЛогаВФайл;appender.dbgfile.level=DEBUG;appender.dbgfile.file=%1", 680 | ФайлЛога); 681 | 682 | УстановитьПеременнуюСреды("LOGOS_CONFIG", ЗначениеПеременнойСреды); 683 | Логирование.ОбновитьНастройки(); 684 | 685 | // Когда 686 | Лог1 = Логирование.ПолучитьЛог("log1"); 687 | Лог1.Отладка("Сообщение1"); 688 | 689 | Лог2 = Логирование.ПолучитьЛог("log2"); 690 | Лог2.Отладка("Сообщение2"); 691 | 692 | Файл = Новый Файл(ФайлЛога); 693 | 694 | // Тогда 695 | Ожидаем.Что(Файл.Существует(), "Файл с логами создан").Равно(Истина); 696 | 697 | Лог1.Закрыть(); 698 | Лог2.Закрыть(); 699 | 700 | ЧтениеТекста = Новый ЧтениеТекста(ФайлЛога); 701 | ТекстЛога = ЧтениеТекста.Прочитать(); 702 | ЧтениеТекста.Закрыть(); 703 | 704 | СтрокиЛога = СтрРазделить(ТекстЛога, Символы.ПС, Ложь); 705 | 706 | Ожидаем.Что(СтрокиЛога.Количество(), "количество залоггированных сообщений").Равно(2); 707 | Ожидаем.Что(СтрокиЛога[0], "Первая строка лога").Равно("ОТЛАДКА - [log1] - Сообщение1"); 708 | Ожидаем.Что(СтрокиЛога[1], "Вторая строка лога").Равно("ОТЛАДКА - [log2] - Сообщение2"); 709 | 710 | КонецПроцедуры 711 | 712 | Процедура Тест_ДолженПроверитьПриемственностьИерархииЛогов() Экспорт 713 | 714 | // Дано 715 | 716 | ФайлЛога = ВременныеФайлы.НовоеИмяФайла("log"); 717 | 718 | ЗначениеПеременнойСреды = СтрШаблон("logger.mainlog=DEBUG, dbgfilehierarch;appender.dbgfilehierarch=ВыводЛогаВФайл;appender.dbgfilehierarch.level=DEBUG;appender.dbgfilehierarch.file=%1", 719 | ФайлЛога); 720 | 721 | УстановитьПеременнуюСреды("LOGOS_CONFIG", ЗначениеПеременнойСреды); 722 | Логирование.ОбновитьНастройки(); 723 | 724 | // Когда 725 | Лог1 = Логирование.ПолучитьЛог("mainlog.sublog1"); 726 | Лог1.Отладка("Сообщение1"); 727 | 728 | Лог2 = Логирование.ПолучитьЛог("mainlog.sublog2"); 729 | Лог2.Отладка("Сообщение2"); 730 | 731 | Лог3 = Логирование.ПолучитьЛог("mainlog.sublog1.subsublog"); 732 | Лог3.Отладка("Сообщение3"); 733 | 734 | Файл = Новый Файл(ФайлЛога); 735 | 736 | // Тогда 737 | Ожидаем.Что(Файл.Существует(), "Файл с логами создан").Равно(Истина); 738 | 739 | Лог1.Закрыть(); 740 | Лог2.Закрыть(); 741 | Лог3.Закрыть(); 742 | 743 | ЧтениеТекста = Новый ЧтениеТекста(ФайлЛога); 744 | ТекстЛога = ЧтениеТекста.Прочитать(); 745 | ЧтениеТекста.Закрыть(); 746 | 747 | СтрокиЛога = СтрРазделить(ТекстЛога, Символы.ПС, Ложь); 748 | 749 | Ожидаем.Что(СтрокиЛога.Количество(), "количество залоггированных сообщений").Равно(3); 750 | Ожидаем.Что(СтрокиЛога[0], "Первая строка лога").Равно("ОТЛАДКА - [mainlog.sublog1] - Сообщение1"); 751 | Ожидаем.Что(СтрокиЛога[1], "Вторая строка лога").Равно("ОТЛАДКА - [mainlog.sublog2] - Сообщение2"); 752 | Ожидаем.Что(СтрокиЛога[2], "Третья строка лога").Равно("ОТЛАДКА - [m.sublog1.subsublog] - Сообщение3"); 753 | 754 | КонецПроцедуры 755 | 756 | Процедура ТрассироватьСообщенияЛога(Знач КоллекцияСообщений = Неопределено) 757 | Если КоллекцияСообщений = Неопределено Тогда 758 | КоллекцияСообщений = мСообщенияЛога; 759 | КонецЕсли; 760 | Для Счетчик = 0 По КоллекцияСообщений.ВГраница() Цикл 761 | Сообщить(СтрШаблон("[%1] = <%2>", Счетчик, КоллекцияСообщений[Счетчик])); 762 | КонецЦикла; 763 | КонецПроцедуры 764 | 765 | Функция ПутьКТестам() 766 | ПутьКТестам = ОбъединитьПути(ТекущийСценарий().Каталог, "..", "tests"); 767 | Возврат ПутьКТестам; 768 | КонецФункции 769 | 770 | //////////////////////////// 771 | // Методы аппендера 772 | 773 | Процедура Вывести(Знач Сообщение, УровеньСообщения) Экспорт 774 | мСообщенияЛога.Добавить(Сообщение); 775 | КонецПроцедуры 776 | 777 | Процедура Закрыть() Экспорт 778 | мСообщенияЛога = Неопределено; 779 | КонецПроцедуры 780 | --------------------------------------------------------------------------------