axaxa_man
@axaxa_man
web developer

Почему выводить логи через System.out.print плохо?

Очень часто где натыкаюсь на то, что использовать system.out.print для логов плохо, но какой-то аргументированной позиции не наблюдал?
Не могли мне помочь разобраться в этом вопросе, поделиться ссылкой, которую я упустил и т.д
Спасибо
  • Вопрос задан
  • 3279 просмотров
Решения вопроса 3
jaxtr
@jaxtr
JavaEE/Spring-разработчик
Потому что использование логгеров, в отличии от System.out, позволяет менять уровни логгирования или даже отключать его на лету. А в целом какой-то серьёзной разницы нет.
Ответ написан
Комментировать
@void_phoenix
Для фреймворков логирования есть конфигурация, управляющая фреймворком, которая позволит вам, например, выводить только ошибки, или изменить место в которое выгружаются логи. Более того, можно сделать так чтобы часть логов выгружалась в одном место, а часть в другое. Если у вас логи пишутся в стандартный вывод и и вдруг вы решили хранить их как-то по другому вам нужно будет не поменять пару строк в конфиге, а искать все вызовы System.out и заменять на что-то другое. В конченом итоге вы переизобретете что-то похожее на log4j, только потратив кучу времени и сил.

P.S. Еще log4j, например, может записывать логи в другом потоке, а сам вызов логирования будет асинхронным. Если у вас критичная к скорости выполнения часть программы, то System.out может замедлять ее работу.
Ответ написан
Комментировать
pi314
@pi314
Президент Солнечной системы и окрестностей
Вывод через System.out - это не "плохо", а всего-навсего "плохо чаще чем хорошо". Если кто-то дает такой совет, то имеет ввиду при этом "по сравнению с использованием логгирующего фреймворка". На самом деле оба подхода имеют свои достоинства и недостатки, просто, как правило, для более-менее сложных и, особенно, чувствительных к производительности систем преимущества использования фреймворков в подавляющем большинстве случаев очевидно перевешивают недостатки.

Производительность.
Если делать вывод через System.out, он всегда будет синхронным, т.е. поток будет ждать завершения операции. И изменить это потом нельзя, не трогая код. Фреймворк же может буфферизировать вывод, сортировать в очереди и т.д. и, почти всегда по дефолту будет делать вывод в другом потоке. Разумеется, все это не бесплатно (память, потоки), но, по мере роста сложности системы, накладные расходы очень быстро компенсируются общим приростом производительности. Если же говорить только о, непосредственно, IO вывода в консоль, то абсолютные накладные расходы от использования фреймворка (для большинства случаев) пренебрежимо малы.

Удобство использования в разных сценариях.
Если код, например, изначально был под десктоп, а потом его понадобилось перенести на сервере, то вывод System.out, конечно, можно перенаправлять в файлы. Но это придется делать довольно отвратительными внешними костылями (ротация файлов, разные блокировки файлов на Win/Linux). Фреймворк, как правило, предоставляет из коробки решения не только этих очевидных проблем, но и кучу плюшек (типа вывода на серверы логов, в сокеты или даже SNMP), причем, делает это эффективнее среднестатистического костылестроителя и позволяет легко переключаться "на лету". Опять же, не бесплатно. Цена: одна лишняя (по сравнению с System.out, который будет работать всегда и везде) зависимость - от самого фреймворка, (а, реально, еще и ворох транзитивных). Однако, для систем с большим количеством других зависимостей этот недостаток практически незаметен.
Другой екстремальный сценарий: старый, давно проверенный и железобетонно-надежный серверный код, логгинг которого последние три года отправлялся в null, вдруг понадобилось использовать... в консольном приложении. А там System.out на System.out-е :) Та-дам!

Гибкость/Масштабируемость.
Фреймворки предоставляют наборы абстакций (аппендеры, очереди, категории, фильтры и т.д.), позволяющих, не трогая рабочий код, легко переконфигурировать логику вывода логов. Представьте на минутку кривизну костыля, который придется строить вокруг System.out, чтоб, например, временно дублировать в отдельный файл записи, выданные кодом из одного определенного пакета или класса, продублировать вывод на второй сервер логов или, сколько кода придется перелопатить, чтоб покрасить в красный цвет записи, содержащие слово CRITICAL... (а если одновременно под ANSI и под HTML?) :) И какова при этом будет вероятность нечаяно сломать этот костыль или этот код :)

Читаемость/Сопровождаемость кода.
Хоршие фреймворки обычно хорошо спроектированы и, при правильном использовании, позволяют безболезненно обновляться, расширять функционал или даже вообще заменяться на другие с минимальными затратами. И все это - совершенно прозрачно с т.з. программиста, которому достаточно просто вместо "System.out.println(" писать, например, "Logger.log(", и можно перестать нервничать по поводу логов и начать жить :)

Недостатки, собственно, вытекают из преимуществ. Мне, лично, приходят в голову только два с половиной сценария, в которых я бы точно не стал брать фреймворк: 1. написание очень маленькой, тривиальной программы, 1.5. написание иллюстрирующего кода (ответ на Тостере, пример использования чего-то в документации или в багрепорте и т.д.) и 2. написание бенчмарка (чтоб не грузить JVM "неизвестно чем").

Так что, собственно, абсолютно универсального совета "не использовать" нет - есть здравый смысл и конкретные потребности в конкретных случаях.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Atllantis
Да выводить можно как угодно и где угодно.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы