1. Знайомство з логами
Лог – це список подій, що відбулися. Майже як морський журнал чи щоденник. Ну а логер — це об'єкт, за допомогою якого можна вести логування. У програмуванні прийнято логувати майже все. А в Java — все і навіть трохи більше.

Справа в тому, що часто Java-програми — це дуже великі серверні програми без UI, консолі, тощо. Вони обробляють одночасно запити тисяч користувачів і часто при цьому виникають різні помилки. Особливо коли різні потоки починають один одному заважати.
Фактично, єдиним способом пошуку помилок і збоїв, що рідко відтворюються, в такій ситуації є запис у лог/файл всього, що відбувається в кожному потоці.
Найчастіше в лог пишеться інформація про параметри методу, з якими його викликано, всі перехоплені помилки, і ще багато проміжної інформації. Чим повніше лог, тим легше відновити послідовність подій та відстежити причини виникнення збою чи помилки.
Але чим більше лог, тим складніше з ним працювати. Іноді логи досягають кількох гігабайт на добу. Це нормально.
2.Невдалі логи
До логів розробники використовували просто виведення в консолі. Це зручно робити під час дебагу програми – коли в консолі пишеться вся важлива інформація та значення змінних. Але такий лог неможливо використовувати під час звичайної роботи програми.
По-перше, програма може хотіти сама щось вивести в консолі, а користувачу не потрібно бачити службову інформацію, призначену для програміста.
По-друге, розмір буфера консолі обмежений, багато туди не напишеш.
По-третє, інформацію про помилки програми, яка збирається за довгий час, потрібно надіслати розробникам програми. І найзручніше писати всю цю інформацію одразу у файл.
Першу проблему розробники швидко вирішили: вигадали ще один потік виведення — System.err
. Ви можете писати в нього повідомлення, і вони будуть надсилатися в окремий потік, а не в стандартну консоль.
І навіть проблему із записом у файл вдалося вирішити:
// Визначаємо файл, до якого будемо писати лог
System.setErr(new PrintStream(new File("log.txt")));
// Виводимо повідомлення
System.err.println("Повідомлення 1");
System.err.println("Повідомлення 2");
// Виводимо повідомлення про помилку
try {
throw new Exception("Повідомлення про помилку");
} catch (Exception e) {
e.printStackTrace();
}
Але навіть у такому вигляді це не вирішувало всієї проблеми, тому вирішили створити спеціальну бібліотеку, яка писала б повідомлення лога у файл. Щоб вона робила це розумно і дозволяла гнучко налаштовувати фільтри подій та даних, що логуються.
Весь процес логування по суті складається з трьох частин:
- Перша частина – це збір інформації.
- Друга частина – це фільтрування зібраної інформації.
- Третя частина – це запис відібраної інформації.
3. Знайомство з логером log4j
Першим популярним логером в Java-спільноті став логер log4j
. Підключити його до проєкту дуже просто: для цього потрібно додати лише кілька рядків до вашого pom.xml
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>2.2.17</version>
</dependency>
Взаємодія твоєї програми з таким логером виглядатиме приблизно так:
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;
}
}
}
Тут відбуваються три речі:
Зеленим кольором виділено створення об'єкта Logger
. Об'єкт зберігається до статичної змінної для зручної роботи з ним. Також до методу getLogger()
передається інформація про клас, в якому відбувається збір інформації.
Синім кольором виділено рядок, де ми логуємо інформацію, що має цінність лише під час дебагу. Для цього використовується спеціальний метод – debug()
Ну і нарешті, червоним кольором виділено рядок, де ми зберігаємо в лог виняток, який виник. Винятки – це потенційні помилки, тому для запису в лог використовується метод error()
.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ