Hello guys! Welcome to a new video where i
will show how to configure and use the loggers. I will show how to use the Slf4J interface and
the logback and log4J loggers. All of these in my Spring Boot application. If you're ready, i
will just ask you to click on the subscribe button and let's go. By default, a Sprint
Boot application is ready to accept using loggers in the code. In fact,
it already has an interface, Slf4J, and a logger, logback, ready to be
used. Let's see how to use the loggers. As i have lombok installed, i can directly use the
annotation Slf4j to create a logger in my class. With the curly bracket, i can replace the variable
value inside the string. Why using the curly brackets and not the string concatenation? In this
case, i am logging at the info level. I may have my logger configured to print info and
higher levels or only print warnings and higher levels. If my log may not be printed, with
the string concatenation, i have the operation of the concatenation done even if my log won't
be printed. With the variable replacement, if my log won't be printed the operation of the
replacement won't be done. This will afford me some CPU operations. Especially, if i write a
lot of logs in different levels. But what are the levels? And how to use them? There are five levels
of logs: error, warning, info, debug and traces. Each of those levels accept a single message to
be printed or with variables to be replaced inside the message. As said, the replacement will be done
only if needed. And with each of those levels, i can also print an exception stacktrace. If i
pass an exception object as the last parameter, the logger will print first my message and then
the exception stacktrace. But which level to use in each case? The error level should be used to
inform about a non-recoverable error. This means that the application can't continue with the
workflow. This means that the request must stop right now and return some 500 HTTP code with an
associated message. This occurs like a missing configuration, a network problem or an unavailable
external service. My application needs this configuration to be fetched, or this external
service to be requested. If it's not available, i can't answer the user's request. The warning
also informs me about an error, but my application can continue with some work around. I may have
some network problems with my external service. But i have some old values in the cache. I can
answer the user's request. Maybe not the best way, but i can do something. The info level is there to
audit some user's behavior. Like when the user's logged in, the users change a configuration,
the users try to upload an invalid file. This example may also be included in the warning
level. The debug level is more likely to obtain enough information to trace a problem and try
to reproduce it locally. I may print the input parameters for a complicated algorithm. And
finally, the trace level is like the debug, try to reproduce a behavior locally, but this time
logging all the inner steps of the complicated algorithm. The debug level will print the inputs
and outputs. And the trace level will also print all intermediary steps. But the main point of
those logs is the later propose. Those logs should be written consequently to be read afterwards.
I can easily trace a bad behavior from the logs, but i need the logs to be good enough, with
enough information to be useful. It's better to write too many logs than not enough. I can
limit and filter the logs in the configuration. Okay, i've written my first line of log, but
what do they look like with no configuration. Okay, this is fine. I think i
have enough information to start. But let's take a deeper look to the configuration. If i look at the dependencies i may
see which logger is used by default. I can see that logback is used. Log4J is
also here, but it's only an interface, an api that needs something more to
work. Let's start by fine-tuning logback. i will configure my logger to print at the
same time to the console and to a file. Those are appenders. I need two appenders. This is to avoid the file growing with no limit.
I use a rolling strategy. When a file reach 10 megabytes, it creates a new file and
rename the old one following this pattern. Here, i define that the root configuration
will print info logs and higher levels, using both the file and the console appender. I also want my logs to use a more detailed
log level the debug level, and also use the file and console appenders. And now i want
to specify which is the format of the logs. Here, first i specified the date and time. Then
the log level. The thread which is running my application. The class which is printing the
log my message or my exception. And i will use this format for both the file and the console.
Nevertheless, i may want the console appender to print the same information but in a more
readable way, with limited columns of characters. Here, i group the date on the log level
to print no more than 30 characters. Here, i group the thread and the class
to print no more than 30 characters but not less than 30 characters. This will
make a column where the message will start to be printed always at the
same column. Let's see the result. Here, i see that my class level is translated
to 30 characters i also see that the date and the log level have a fixed size. And then i have
my message printed always at the same column. Which is easier to read. Okay, i have my logback
configuration ready. I can also try to do the same with log4j to see the differences. But first,
let's see the difference between logback, log4j and slf4j. First of all, i've used slf4j. slf4j
is an interface. I can have any logger behind and my code won't change if i update my dependencies
or my configuration. So why to choose logback as a logger? logback is natively included in a Spring
Boot application. It automatically applies changes on the configuration file. It handles gracefully
the files: if there is a missing file, if there is a file too big, or if multiple threads write to
the same file. It has a fine-tuning filtering. Not only by level but by class. And it has some
appenders like the HTTP-access one which allows to read the incoming requests with detailed
information. And what about log4j2? Yes, because it's already the second version. It also
reloads automatically upon configuration changes. It handles file changes and rotation. It also
has fine-tuning filtering. And HTTP-access logs. But it also has a low latency asynchronous
logs. And the better garbage collector, which improves the time response and time
performance. So, log4j is a better option. You may have heard about some vulnerabilities
about log4shell. But this only affects some specific versions. i will make another video
about this vulnerability. Let's configure now my application to use the log4j logger. First of
all, i need to exclude the logback dependency. Now, create the configuration file. As before, i also want two
appenders: the console and the file. The pattern is quite similar as the logback
one. Nevertheless, i can't group by values. Here, i can compress my files
directly with the extension. I can also fine-tune the
trigger to roll the files. And now the logger's details as before. Okay, that's all. Let's make a quick recap.
I've written the logs using directly slf4j, as it's an interface. By default,
Spring Boots has logback already configured. If i want to fine-tune my logback
configuration i need to create a logback file. I've added two appenders: one to write to the
console and the second one to write to a file. To use lock4j, i must exclude logback and create
log4j.xml file. And the configuration for log4j is quite similar as the one for logback. That's
all for this video. I hope you liked it. If so, click on the like button and
see you in the next video. Bye!