JavaRush /Курсы /JSP & Servlets /Уровни событий

Уровни событий

JSP & Servlets
5 уровень , 2 лекция
Открыта

3.1 Список уровней событий

Логирование – это процесс записи каких-либо событий, которые происходят во время работы программы. Ваша обязанность как программиста — запротоколировать все важное, потому что потом, когда на production будут странные и/или серьезные ошибки, кроме этих логов у вас больше ничего не будет.

Любая ошибка будет устранена в разы быстрее, если у вас будет вся информация о ней и обо всех предысториях вызовов. Но отсюда следует простой вывод – логировать вообще все: вызовы всех методов, значения всех параметров.

Это тоже не выход – слишком много информации так же плохо, как и слишком мало. Нам нужно умное логирование. Сделанное человеком для человека. И тут мы подходим к первому факту про логирование – все записи в лог еще во время их создания делятся на категории.

 Список уровней событий

Программист, когда пишет какое-нибудь событие в лог, должен сам решить, насколько это важная информация. Уровень важности события выбирает автор сообщения. В log4j существует 5 уровней важности логируемой информации:

  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL

Ниже расскажем о них подробнее.

3.2 DEBUG

Уровень DEBUG считается наименее важным. Информация, которая пишется в лог с таким уровнем важности, нужна только во время дебага приложения. Для того чтобы записать в лог информацию нужную во время дебага используется метод debug().

Пример:


class Manager {
    private static final Logger logger = LoggerFactory.getLogger(Manager.class);

    public boolean processTask(Task task) {
        logger.debug("processTask id = " + task.getId());
        try {
            task.start();
            task.progress();
            task.complete();
            return true;
        } catch (Exception e) {
            logger.error("Unknown error", e);
            return false;
        }
    }
}

Обрати внимание, метод debug находится в самом начале метода (метод еще не успел ничего сделать) и пишет в лог значение переданной в метод переменной. Это самый частый сценарий использования метода debug().

3.3 INFO и WARN

Следующие два уровня – это INFO и WARN. Для них существуют два метода – info() и warn().

Уровень INFO используется просто для информационных сообщений: происходит то-то и то-то. Когда начинаешь разбор ошибки в логе, бывает очень полезно почитать ее предысторию. Для этого отлично подходит метод info().

Уровень WARN используется для записи предупреждений (от слова warning). Обычно с таким уровнем важности пишется информация о том, что что-то пошло не так, но программа знает, как поступить в данной ситуации.

Например, в процессе записи файла на диск, выяснилось, что такой файл уже существует. Тут программа может записать в лог предупреждение (warning), но показать пользователю диалоговое окно и предложить выбрать другое имя файла.

Пример:


class FileManager {
    private static final Logger logger = LoggerFactory.getLogger(FileManager.class);

    public boolean saveFile(FileData file) {
        logger.info(“сохраняем файл ” + file.getName());
        boolean resultOK = SaveUtils.save(file);
        if (resultOK) return true;

        logger.warn(“проблема с записью файла ” + file.getName());
        String filename = Dialog.selectFile();
        boolean result = SaveUtils.save(file, filename);
        return result;
    }

3.4 ERROR и FATAL

И наконец два самых важных уровня логирования – ERROR и FATAL. Для них тоже есть специальные методы с одноименными названиями: error() и fatal().

Ошибки тоже решили разделить на две категории – обычные ошибки и фатальные ошибки. Фатальная ошибка чаще всего приводит к аварийному закрытию приложения (для десктопных приложений) или падению веб-сервиса (для веб-приложений).

Еще хороший пример – это операционная система Windows. Если у тебя просто упала программа, то с точки зрения операционной системы – это Error. А если упала сама операционная система и вы видите синий экран смерти Windows, то это уже Fatal error.

В Java-приложениях чаще всего события Error и Fatal связаны с возникающими исключениями. Пример:


class Manager {
    private static final Logger logger = LoggerFactory.getLogger(Manager.class);

    public boolean processTask(Task task) {
        logger.debug("processTask id = " + task.getId());
        try {
            task.start();
            task.progress();
            task.complete();
            return true;
        } catch (Exception e) {
 logger.error("Unknown error", e);
            return false;
        }
    }
}

3.5 Что нужно логировать

Разумеется, логировать все подряд не стоит. В большинстве случаев это резко ухудшает читабельность лога, а ведь лог пишется в первую очередь для того, чтобы его читали.

Кроме того, нельзя писать в лог различную личную и финансовую информацию. Сейчас с этим строго и легко можно нарваться на штрафы или судебные процессы. Рано или поздно такой лог утечет на сторону и тогда проблем на оберешься.

Так что же нужно логировать?

Во-первых, нужно логировать начало работы приложения. После того как приложение запустилось, рекомендуется вывести в лог его режим работы и различные важные настройки – так будет проще в будущем читать лог.

Во-вторых, нужно логировать состояние всех третьесторонних сервисов, с которыми твое приложение работает: системы рассылок, любые внешние сервисы. Как минимум нужно залогировать момент подключения к ним, чтобы убедиться, что они штатно работают.

В-третьих, логировать нужно все исключения. Если они ожидаемые, то информацию по ним можно записать компактно. Полная информация об исключениях дает 50%-80% важной информации при поиске ошибки.

Также нужно логировать завершение работы приложения. Приложение должно завершаться штатно и не сыпать при этом в лог десятки ошибок. Часто в этом месте можно найти подвисшие задачи, проблемы с пулом потоков или проблемы с удалением временных файлов.

Обязательно логируй то, что связано с безопасностью и авторизацией пользователя. Если пользователь 10 раз подряд пробует залогиниться или сбросить пароль, эта информация должна быть отражена в логах.

Логируй максимум информации об асинхронных задачах – часто исключения в таких потоках теряются. По асинхронной задаче обязательно логируй ее старт и завершение. Успешное завершение нужно логировать так же, как и проблемное.

Что еще? Запуск задач, выполняемых по таймеру, запуск хранимых SQL-процедур, синхронизацию данных, все, что касается распределенных транзакций. Думаю, для начала хватит. В будущем ты сам дополнишь этот список.

Комментарии (10)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Олег Уровень 106 Expert
31 августа 2024
Полезная штука, всё понятно
Иван Корниенко Уровень 109
18 мая 2024
Так есть же еще уровень trace, или я что-то путаю?
Олег Уровень 79 Expert
24 декабря 2023
Пункт 3.4 Ошибки ERROR и FATAL Странно, но приведённый пример абсолютно такой же как и для DEBUG только цвет шрифта изменили.... А где же специяльные методы error() и fatal() ???
17 декабря 2023
"Рано или поздно такой лог утечет на сторону и тогда проблем НА оберешься."
Дмитрий Саргаев Уровень 76 Expert
5 сентября 2023
Может я чего-то не понимаю... классы из примера: FileData, SaveUtils, Dialog - это мы сами ручками создавать должны? или есть какая-то магическая библиотека Методы task.progress(), task.complete() я тоже не смог найти в JDK ... What is that?
Надежда Уровень 104 Expert
8 июня 2023
/* Комментарий удален */
RFedorenkov Уровень 1
15 июня 2023
The logger reference is not a constant, but a final reference, and should NOT be in uppercase. A constant VALUE should be in uppercase. private static final Logger logger = Logger.getLogger(MyClass.class); private static final double MY_CONSTANT = 0.0; https://stackoverflow.com/a/1417216
Михаил Уровень 51
14 сентября 2022
В примере с INFO в 7й строке не хватает возвращаемого значения "true"
Станислав Уровень 83 Expert
11 ноября 2023
а в 8-ой как будто "else" пропущен ... или зачем тогда в любом случае в лог писать о проблеме с записью файла
Jacque Frescov Уровень 29
29 августа 2022
У тебя упала программа - Error Вышел синий экран - Fatal error Хейтеры, люблю вас!