All streams
Search
Write a publication
Pull to refresh
-2
0
Send message

оставляю следы существования. Не более того.

извиняюсь за 3й ответ Вам подряд. Тему затронули обширную сразу.
Так вот, забыл сказать самое важное: если Вы хотели бы использовать Чёрный ящик у себя в проектах, но именно с форматом Tree — пожалуйста дайте знать. Мы подготовим реализацию BlackBoxTree. Это не займёт много времени.


Подход именно такой: под каждый формат — отдельная реализация.

Ещё хотел попросить не оч. сильно анализировать пример, его трудно сделать наглядным без контекста самого приложения. Так что он больше для общего понимания.


Лучше всего попробуйте на практике Чёрный ящик.

Привет!


Изначально использовали иерархический формат — XML (с XSD на соответствующим классовой модели Groovy AST):
image


  • Исключение
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <rootAstNode xsi:type="MethodNode" methodName="foo" className="io.infinite.blackbox.SandBox"
             startDateTime="2018-10-22T16:17:40.843+04:00" lineNumber="29" columnNumber="5" lastLineNumber="35"
             lastColumnNumber="6" xmlns="https://i-t.io/blackbox/groovy/2_x_x/BlackBox.xsd"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <astNodeList/>
    <argumentList>
        <argument argumentClassName="java.lang.String" argumentName="bar">
            <argumentValue>foobar</argumentValue>
        </argument>
    </argumentList>
    <exception exceptionDateTime="2018-10-22T16:17:40.913+04:00">
        <exceptionStackTrace>java.lang.Exception: Bar can not be foobar
            at io.infinite.blackbox.SandBox$_foo_closure1$_closure3.doCall(SandBox.groovy:32)
            at io.infinite.blackbox.SandBox$_foo_closure1$_closure3.doCall(SandBox.groovy)
            at io.infinite.blackbox.BlackBoxEngine.expressionEvaluation(BlackBoxEngine.groovy:70)
            at io.infinite.blackbox.BlackBoxEngine$expressionEvaluation$3.call(Unknown Source)
            at io.infinite.blackbox.SandBox$_foo_closure1.doCall(SandBox.groovy:32)
            at io.infinite.blackbox.SandBox$_foo_closure1.doCall(SandBox.groovy)
            at io.infinite.blackbox.BlackBoxEngine.executeMethod(BlackBoxEngine.groovy:175)
            at io.infinite.blackbox.BlackBoxEngine$executeMethod$1.call(Unknown Source)
            at io.infinite.blackbox.SandBox.foo(SandBox.groovy)
            at io.infinite.blackbox.SandBox.run(SandBox.groovy:40)
        </exceptionStackTrace>
    </exception>
    </rootAstNode>
  • Нормальное выполнение
    <rootAstNode startDateTime="2018-10-22T15:59:49.120+04:00" xmlns="https://i-t.io/logging/groovy/2_x_x/BlackBox.xsd"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <astNodeList>
        <astNode xsi:type="MethodNode" methodName="foo" className="io.infinite.blackbox.SandBox"
                 startDateTime="2018-10-22T15:59:49.156+04:00" lineNumber="29" columnNumber="5" lastLineNumber="32"
                 lastColumnNumber="6">
            <argumentList>
                <argument argumentClassName="java.lang.String" argumentName="bar">
                    <argumentValue>z</argumentValue>
                </argument>
            </argumentList>
            <astNodeList>
                <astNode xsi:type="Statement" statementClassName="ReturnStatement"
                         startDateTime="2018-10-22T15:59:49.217+04:00" sourceNodeName="BlockStatement:statements"
                         lineNumber="31" columnNumber="9" lastLineNumber="31" lastColumnNumber="19">
                    <restoredScriptCode>
                    <astNodeList>
                    </astNodeList>
                </astNode>
                <astNode xsi:type="Expression" expressionClassName="VariableExpression"
                         startDateTime="2018-10-22T15:59:49.226+04:00" sourceNodeName="ReturnStatement:expression"
                         lineNumber="31" columnNumber="16" lastLineNumber="31" lastColumnNumber="19">
                    <restoredScriptCode>bar</restoredScriptCode>
                    <astNodeList>
                    </astNodeList>
                    <expressionValue className="java.lang.String">
                        <value>z</value>
                    </expressionValue>
                </astNode>
            </astNodeList>
            <methodResult className="java.lang.String">
                <value>z</value>
            </methodResult>
        </astNode>
    </astNodeList>
    </rootAstNode>

Но из-за большой вложенности стеков всё это сильно съезжало вправо, и становилось ещё менее читаемым на практике. Поэтому сделали просто читабельный текстовый вывод.


Как показывает практика, в нём не так важна красота — чаще всего знаешь, что именно искать — и ищешь с помощью ctrl-f. А вот минимализм — помогает.


Так что текущая реализация — базовая. Имеет смысл вариации делать именно как отдельные реализации; Базовый API — карбюратор. Если есть желание — можете поэкспериментировать с ним.


А если мыслить масштабно — то это вообще дело не программы, а Kibana/Splunk/Grafana. В этом случае вообще не так критичен формат вывода из программы. Главное чтобы он был единообразен.


Это если в общем виде — какие строки и сообщения логировать.


Если говорить про частные случаи форматирования отдельных сообщений (например method exception — как вы написали выше) — это должно решаться на уровне настроек логгера.
Мы рекомендуем использовать логгер Бобину.
Вот как бы выглядили настройки Бобины для Вашего примера:


Bobbin.yml:


destinations:
  - name: io.infinite.bobbin.config.ConsoleDestinationConfig
    levels: [error]
    formatThrowable: ("error\n    time $dateTime\n    class $className\n    type ${throwable.class.name}\n stack ${exceptionUtils.stacktrace(throwable)}")

Это если без реализации Tree. А так, надо бы реализовать на Java его, отличный формат! Спасибо за наводку.

Согласен, конечно. Это лишь вопрос трудозатрат — использовать готовое решение, или настраивать в конкретных проектах.
На всякий случай повторюсь, "Чёрный ящик" не требует от программиста, использующего его, каких-либо трудозатрат, кроме добавления аннотации @BlackBox к методам (или даже к классам целиком). Такая себе прозрачность использования получается — и никому не придётся разбираться как реализовано это через AOP (не все в нём хорошо разбираются).


Но ещё раз спасибо — Вы подтолкнули подумать — можно ли сделать Java реализацию "Чёрного ящика" с помощью AOP (как библиотеку). Пока рассматривался вариант аннотации и CGLIB.

Привет! Спасибо за комментарий.


Spring AOP точно есть, ApsectJ тоже (насколько я знаю, но не пробовал сам).


Spring AOP работает медленно. "Чёрный ящик" встраивается на этапе компиляции и не замедляет работу приложения. А AspectJ требует отдельного компилятора, что затрудняет переносимость библиотек, использующих его.


Так что AST наиболее беспроблемный вариант. А вот насчёт гибкости — разве в общем случае AOP более гибкий, чем AST API?


Как бы то ни было, мы позаботились об этом в "Карбюраторе" (абстрактный AST API, используемый в "Чёрном ящике") — он гибко настраивается (даже есть экстернализированная конфигурация), и предоставляет доступ ко всем нужным мета-данным этапа компиляции на этапе исполнения.


Но интересно узнать Ваше мнение насчёт этого.

Спасибо, это по ошибке было. Исправил.
Убрал Spring Boot из cobol-lib. В cobol-cli оставил только Spring Boot Loader (чтобы Gradle делал человеческий толстый jar), но он мало места занимает.


https://bintray.com/infinite-technology/io.i-t/download_file?file_path=io%2Fi-t%2Fcobol-cli%2F1.0.1%2Fcobol-cli-1.0.1.jar

Добавил тест, а также выпустил CLI релиз (для запуска из командной строки):
https://github.com/INFINITE-TECHNOLOGY/COBOL/releases/tag/1.0.0


Можете скачать и попробовать у себя.


Кстати, есть и облачная версия (она уже пол года работает): https://i-t.io/Cobol


(Тестов будет больше, конечно, в дальнейшем. Это только для примера пока.)

ну и вообще — электричество одно из первых результатов тех. революции конца 19 века.
Там ВСЁ продумано уже. Не нужно изобретать велосипед.

я имел в виду DC полярность. Тут люди хотят DC 3\5V подавать от щитка.

Придётся провода с высоким AWG использовать и качественной изоляцией. А так-же их скручивать. Ну и полярность никто не отменял. Так что 220 — ОК. НЕ анахронизм.

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

Очень извиняюсь за отсутствие тестов и документации. Тесты были выпилены при публикации кода, т.к. содержали проприетарные копибуки.
Тесты и документация будут обязательно добавлены в скором времени. У нас сейчас происходит экспоненциальный рост количества проектов, что требует внедрения операционной методологии. И она уже разработана. "Какая методология?" — в нашей следующей статье. Это будет нечно удивительное.

думаю, там не-технические причины основные. Но помимо этого — COBOL очень крутой язык, реально созвучный бизнес-процессам. И сообщества COBOL до сих пор очень дружелюбны и полезны.


Скажем так — в чистом виде Java очень сильно отстаёт по наглядности разработки от COBOL. Программисты больше голову ломают над техническими проблемами, чем над бизнес-алгоритмами. Это же применимо и к PL/SQL. Но у этих языков всё же есть проблемы масштабируемости, с этим не поспоришь.

Спасибо за поддержку! Всё так. Громковато сказано, согласен.

Статья хорошая, я бы даже сказал отличная. Важное дело делаете — продолжайте освещать эту тему, а то в Интернете каша полная по ней, полнейшая путаница на stack overflow и 90% людей не понимают как это работает и как должно работать. Страшно подумать сколько уязвимостей сейчас существует из-за неправильно настроенной авторизации на сайтах.


И самое печальное, что в 2020 году до сих пор нет готовых решений plug and play, которые не требуют глубоких технических навыков и программирования для внедрения OAuth2 и Open ID Connect. Но есть перспективная тенденция: SECaaS, и например наша некоммерческая организация готовит SECaaS платформу которая в этом году произведёт революцию в этой сфере. И она независима (хоть и поддерживает/совместима) от OAuth2 и Open ID Connect.

будет добавлено в 3.1.0. Спасибо. Это уже 2я фича от Вас.
привет! Спасибо за комментарий.
По Вашему указанию, в 3.1.0 добавим возможность указывать путь к конфигу Бобины. Это не сложно и может быть полезно.

Runtime изменение настроек Бобины не поддерживается, требуется перезапуск. Причина — простота и предсказуемость как кода так и эксплуатации. Это сознательное решение.

Интерфейс программной настройки — вот это интереснейший момент! Мы считаем что код логирования НЕ нужно писать вообще! И задачу эту успешно решили: код логирования генерируется и добавляется автоматически на этапе компиляции с помощью аннотации BlackBox (https://github.com/INFINITE-TECHNOLOGY/BLACKBOX). Всё что требуется — задавать что именно логировать с помощью аргумента аннотации (применимой и ко всему классу) — только ошибки методов, вызовы методов (с результатами), каждый statement, каждый expression. Эта аннотация поддерживается только в Groovy компиляторе пока — но раскроем секретные планы — идёт работа над реализацией этого функционала с помощью cglib на Java.

В общем целом — это наш основной постулат — минимизация (в идеале полная автоматизация) инфраструктурного кода. И логирование (как например и авторизация) — это именно такой инфраструктурный код. Если используете Groovy — попробуйте BlackBox. Мы полностью доверили ему весь код логирования. Работает отлично в паре с Бобиной :) (но может и с любыми SLF4J логгерами). Скоро будет отдельный пост по BlackBox.
у Вас неправильное отношение к опен сорсу.

Опенс Сорс — основная работа.

Все остальные работы — вторичны.
альфа — не оферта. Как сами написали — альфа для тестирования.

Information

Rating
Does not participate
Registered
Activity