Комментарии 31
Попробуйте Bobbin сейчас: Gradle: compile "io.infinite:bobbin:2.0.0"
А в каком репозитории находятся артефакты? В Maven Central, на сколько я вижу, их пока нет.
*Bobbin является Open Source проектом под лицензией Apache.
Может стоило дать ссылку на исходники?
Я правильно понимаю что вот его репозиторий: https://github.com/INFINITE-TECHNOLOGY/BOBBIN
В статье ни одной необходимой ссылки нет, а жаль.
Если перейти с найденного на GitHub репозитория, то можно найти и домашнюю страницу проекта, а там и документацию и уже в самом конце документации есть указание на то, что библиотеки лежат на отдельном репозитории внутри Bintray: https://dl.bintray.com/infinite-technology/m2
И этот репозиторий, естественно, нужно прописывать и в Maven и в Gradle проектах, без этого простое добавление зависимости приведёт к ошибке сборки.
если честно, я очень боялся что лишние ссылки будут выглядеть как само-PR (очень хочу чтобы этот проект стал «народным»). Поэтому понадеялся на авось, что у всех JCenter прописан. Прошу прощения!
Пожалуйста, пропишите репозиторий JCenter и попробуйте собрать.
PS: m2 репозиторий это внутренний репозиторий для m2, артефакты из него автоматически привязываются к JCenter.
Проект на Gradle вроде собирается, но лучше не смотреть в вашу документацию и jcenter
подключать как положено через repositories {jcenter()}
вместо repositories {maven {url "https://dl.bintray.com/infinite-technology/m2" }}
А вот с maven всё ещё веселее:
- Тоже проблемы в документации: там сказано что нужно указать jcenter в
pom.xml
, но пример конфига указывает на изменения вsetting.xml
- Ваша либа зависит от
org.codehaus.groovy:groovy-all:2.5.4:jar
, а такого файла нет ни в Maven central ни в JCenter в результате Maven не находит зависимость и сборка падает
Документация на вики проекта в github обновленная, пожалуйста используйте ее:
github.com/INFINITE-TECHNOLOGY/BOBBIN/wiki
Сайт (не буду указывать ссылку дабы избежать рекламы) немного отстает и будет скоро обновлен!
"fileName": "\"./LOGS/ALL/WARNINGS_AND_ERRORS_${date}.log\""
Мои глаза! Зачем в имени файла дополнительные кавычки?
При этом вывод планировался в XML. Так что мы любим и уважаем XML и XSD.
Просто пока есть только конфиг использующий Jackson databind.
Я буду рад добавить фичу! Делать XML конфиг? (будем рады сослаться на Ваш профиль в Хабре в описании issue на Гитхабе!)
Отличный вопрос! и я рад продемонстрировать гибкость скриптовой настройки, можно настроить без escape characters:
"fileName": "'./LOGS/'+level+'/'+className+'/'+threadName+'/log.txt'"
Выглядит тоже не очень! Но идея в скриптах — возможно кто-то из пользователей найдет идеальный вариант. Каждый может использовать свой подход к написанию скрипта.
Ограничение вызвано интерпретацией кода в GString на этапе компиляции Груви класса, при использовании «$переменная».
идея в скриптах
Это я понял, я не понял почему
"fileName": "./LOGS/ALL/WARNINGS_AND_ERRORS_${date}.log"
нельзя на этапе разбора json-объекта предобработать (то же закавычивание значения), чтобы для пользователя это было прозрачно.
Но опыт показывает, что иногда пользователю может наоборот помешать доп. обработка — поэтому пока было сделано так. Пример:
"fileName": "threadName"
В этом случае имя лог файла равно имени треда. Но если взять насильно это в кавычки (за пределами JSON), смысл потеряется и переменная станет константой.
В этом случае имя лог файла равно имени треда.
Это ни разу не очевидно. Для консистентного поведения в таком случае настройка должна выглядеть так:
"fileName": "\"${threadName}\""
При таком подходе даже человеку незнакомому с Вашей библиотекой будет понятно, что это не просто строка, но какой-то плэйсхолдер.
Попробуйте из репозитория Jcenter:
<dependency>
<groupId>io.infinite</groupId>
<artifactId>bobbin</artifactId>
<version>2.0.0</version>
<type>pom</type>
</dependency>
Причина такая на мой взгляд: иначе получается смешение функциональностей и выходит супер библиотека, делающая всё.
А независимая библиотека априори более функциональная и качественная.
Да, так сделано в других логгерах. Например в Logback эти настройки применимы только к FileAppender, но в случае SiftingAppender появляются ограничения: jira.qos.ch/browse/LOGBACK-1442
Поэтому настало время принять правду — в Logback это архитектурно неправильно реализовано… Как Вы думаете?
А вот yaml отличная идея. Добавил заявку: github.com/INFINITE-TECHNOLOGY/BOBBIN/issues/17
Спасибо!
Так что фичи должны быть востребованы, иначе получается мертвый груз затрудняющий рефакторинг.
В идеале набор опций таков:
— xml, json, yaml конфиги
— groovy конфиг
— dsl конфиг
Начнем с yaml добавлять! По остальным проведем небольшой анализ и опрос.
Расскажите, пожалуйста, тестировали ли вы производительность? По каким сценариям? С чем сравнивали?
Насколько хорошо ваш логгер работает с огромными логами? Как ведет себя под длительной (больше суток) нагрузкой?
Расскажу как производилась оптимизация footprint этого логерра по отношению к CPU, RAM и влиянию на GC, а также как выбиралась архитектура и принципы разработки исходя из общей производительности:
— Тестовый стенд представляет собой гибридное Spring Boot приложение, имеющее около 150 постоянных потоков, как синхронизированных, так и постоянно работающих в фоне.
Он использует JPA, Hibernate, Groovy, REST. Стенд нагружался до степени, которая позволила выявить большое количество багов по потокобезопасности.
Влючалось логирование SQL и binding в JPA/Hibernate. Ну и самое главное — стенд использовал Blackbox, который логировал буквально каждый expression в коде бизнес логики. Т.е. вывод примерно 25Мб/с логов. Около 400 одновременно записываемых файлов.
— Была произведена первоначальная оптимизация при помощи нашего другого проекта Speedometer (пока на стадии разработки) — AST профайлер.
— Затем производился последовательный анализ вносимых изменений используя Java Visual VM. Анализировалось потребление CPU и особенно памяти и эффективности GC.
Как результат были выработаны и внедрены следующин принципы:
1-статическая компиляция всех классов (мы используем новый Groovy Enterprise Plugin)
2-отказ от использования синтаксиса форматирования аргументов, использованного в Slf4j (это кошмарная идея была изначальнл в Slf4j)
3-полное отсутствие synchronized блоков и методов
4-отказ от MDC/ThreadLocal — это вызывает проблемы для GC (тем не менее мы оставили поддержку встроенного MDC из Slf4j)
5-минимизация использования коллекций и особенно потокобезопасных коллекций. Это в первую очередь касается “@Memoized” — он очень сильно замедляет работу.
6-для замены Memoized была разработана другая аннотация “@CacheFieldInit”
7-минимизация создания экземпляров классов. По возможности используются только аргументы методов. Это очень сильно помогает GC, и непонятно почему этим пренебрегли в Logback.
8-скрипты из файла настройки статически компилируются в Груви класс используя GroovyClassLoader — это дает наилучшую производительность
9-потокобезопасность строится на принципе потоковой изоляции стеков операндов вызовов методов, избегая необходимость какой-либо синхронизации
Анализировались Heap Dumps, профайлер и разные статистики. Искались memory leaks.
Это был очень стрессовый процесс с пересиживаниями в ночь на протяжении 1.5 месяца. Иногда руки опускались и казалось что все напрасно.
Но конечный итог оправдал все надежды — у меня не было времени сохранить конкретные значения, но скажу так: по Java Visual VM logback выглядел… жирно — по сравнению с нашем логгером.
Если коротко — Bobbin быстрый. Очень быстрый. И экономит память.
Так же есть список todo: посмотреть как влияет opcodes.FINAL на GC в применении к операндам методов; протестировать производительность на других платформах кроме Windows.
Альтернативный Slf4j логгер «Бобина»