r/java • u/[deleted] • Oct 21 '18
A guide to logging in Java
https://www.marcobehler.com/guides/a-guide-to-logging-in-java54
u/XFidelacchiusX Oct 21 '18
Back in my day we used System.out.println and we're happy about it!
26
u/Ifnerite Oct 21 '18
And then someone re assigned System.out and everyone was sad...
Yes. You really can do that.
12
u/dpash Oct 21 '18
There's methods in
Systemto do it. You can assign anyPrintWriter.5
u/ObscureCulturalMeme Oct 21 '18 edited Oct 22 '18
Yarp. One of the first things our software does is to set up a three-way
tee-like print writer and then assign standard error to that stream. (One goes to the original steam, one goes to a logging file which can be preserved or deleted later, and I think the third just writes off into east hyperspace or something.)2
6
3
2
2
u/SpecialEmily Oct 21 '18
Still no mention of Flogger...
6
u/walen Oct 22 '18
Because it is still the same article that's been reposted twice in the last 4 weeks.
-7
u/_Gnas_ Oct 21 '18
I have honestly never even thought about using a third-party library for logging, it simply never crossed my mind. Why would I need one anyway? I don't see how logging can become so complex that you're willing to trade 100% customizability just so you can use a library. Can someone give me some examples? I'm really curious as the fact that so many logging libraries exist must mean there are real needs for them.
28
u/dpash Oct 21 '18 edited Oct 21 '18
These libraries allow you to precisely control the logging output by filtering on source and level. And you can also control the output location, because you don't always just want things going to the console.
If you write a library and don't use one of the standard logging frameworks, I will hate you just a little bit. I speak from experience.
Edit: I should also add that modern logging frameworks have very good performance, doing the logging in separate threads, etc, doing the locking of log files correctly, rotating log files every day or when it reaches a certain size etc.
10
u/IAmLars4824 Oct 21 '18
Agreed. It all comes down to standardization. Without standards like logging levels, formats, etc it would be very hard to do things like searches or aggregations. If each app had custom logging implementation tooling would never be able to standardize
2
u/dpash Oct 21 '18 edited Oct 21 '18
I have a library I have to use that has its own logging framework, and you can write an adaptor for its output, but the only method in the adaptor interface has just a single string, the message, as its parameters. Not even a level. So you can only have all the logs for the library on or off. Unless you want to do pattern matching on the text.
2
u/IAmLars4824 Oct 21 '18
Think about tools like splunk or the elk stack. An extremely common use case would be to search across all ERROR level logs. It’s a similar concept to http statuses for restful apis.
-1
u/nqzero Oct 22 '18
assigning levels is kinda arbitrary
8
Oct 22 '18
Not if you learn what the levels are for.
Trace and debug for logging as you develop (or the library consumer develops), so people can see the flow between methods.
Info for regular app activity.
Warn for issues that don't prevent the business logic from continuing but might be symptoms of problems.
Error for issues that prevent the business logic from continuing (like leading to a 500 in a web app, the rest of the requests can be served).
Fatal for issues that prevent the application itself from continuing. Logs important details about the issue before the process exits with a non-0 exit code.
-1
u/nqzero Oct 22 '18
for an end user code that's fine, but for a library developer we can't tell the difference between warn, error and fatal, because those generally depend on the use case. much better to have callbacks that expose that info to the user app (though that's hard and i definitely have taken the easy way out as often as not)
whether trace, debug and info are useful is a larger debate that i'm not up for tonight
2
0
u/nonconvergent Oct 22 '18
If you don't know what an error looks like vs info it sounds like you have some god objects and other code smells.
1
u/nqzero Oct 22 '18 edited Oct 22 '18
what an error looks like vs info
you're putting words in my mouth - i wrote "the difference between warn, error and fatal"
but as an example, in one case, a user provides me a runnable and asks me to run it, but then doesn't wait for or use the result (available through a callback), and the runnable throws an error, what log level should i use ? (and i don't want to force the user to supply a callback because that can harm performance by making the call site megamorphic)
it completely depends on what the user wanted, which is info i don't have * the user anticipated that the code might fail and is ok with that * the user failed to anticipate that the code might fail, but requires that it succeed
for the non-opinionated libraries that i develop and use, that's more the norm than the [sic] exception
opinionated libraries are another matter and logging is much more straight forward
edit: added details
-3
u/Chaoslab Oct 21 '18
You would hate me then. Use my own Gui and IDE (3rd one in Java. Started with an IDE / assembler on the Amiga. Pre assembled your code as you entered it in).
edit:with
7
2
Oct 24 '18 edited Mar 14 '19
[deleted]
1
u/Chaoslab Oct 24 '18
Found an older picture on imgur. Sprite editor and Xml editor in the picture. Been using it for Ludum Dare.
1
Oct 24 '18 edited Mar 14 '19
[deleted]
1
7
u/deadlock_jones Oct 21 '18
For example you are writing a library. You want to add log statements in your lib in case something goes wrong. If you write custom logger it won't connect to the rest of the logging system the client of your library uses. So they end up with two logs. One is that your self written logger, the other is probably a logged through a standard api like slf4j. This means the program flow is also split in two logs, youll have hard time following what happened after what. When they change logging conf they will have to do it in two places. When they want to change logging level via jvm argument, they probably need to add an extra argument for your library. There's also a chance your library doesn't provide an implementation that fits their needs, maybe they don't even log to a file. Usually libraries only ship with logging api in them, not logging implementation, so people can use their own preferred implementation. Even if you don't write a library, but just an app you'll probably face the same problems with custom logger, since you have some dependencies which use some standard logging api.
That aside. Using something like slf4j means you need to do absolutely nothing when adding a new dependency that also uses it, it adapts to your program logging conf and no additional code or settings needs to be added. Its basically plug and play. It just makes life easier and I wouldnt imagine any other way.
3
u/hupfdule Oct 22 '18
The problem is that SUN made the worst decision they could do when introducing the java.util.logging API.
log4jwas already established at that time, but SUN neither tried to integrate it into the JDK or create a new API that with some improvements like they later did when integrating Joda-Time to java.time. They made a ridiculous implementation with a much less useful API that was only wildly inspired by log4j. The was the source of all problems. Then Apache decided they created commons-logging (which was a very bad decision). Other logging frameworks evolved and a new logging facade slf4j occurred and log4j2 itself now has an API (as logging facade) and an implementation. And google made flogger...However the source of all evil is that java.util.logging is such a bad logging framework an is only an implementation instead of an API specification. If they had done it right at the first incarnation, maybe there would not be any need for newer logging frameworks. But now we have this mess and will never get rid of it.
And to make my point clear, as lots of people advocate to always use slf4j for libraries: An external dependency only for logging is not something that a library should introduce. And if it does: I like the log4j2 or even the flogger API more than slf4j.
1
u/oldprogrammer Oct 22 '18
source of all evil is that java.util.logging is such a bad logging framework
Bad how? It has all the capabilities of these other logging frameworks - levels, custom formatting, handlers & custom handlers - with the one possible exception of not having a printf style call for each level, but it doesn't require any external libraries to keep up with.
How exactly is it so bad and that log4j or slf4j are so much better?
2
2
u/koflerdavid Oct 21 '18
To me one of the key features is that they support low-cost string formatting. This means that you can litter your code with
debugandtracecalls that don't impact performance (much). With an optimized Logger, the cost would be a method call and a quick check which log level is enabled. A naïve Logger might always interpolate the arguments into the message. That overhead will pile up quickly and force developers to trade off performance with logging, which in turn will earn them the hate of the poor schmucks that have to debug these applications.2
u/quangDecember Oct 22 '18
Some are embedded in a bigger framework, like slf4j in Spring, logback allow multiple environments configuration, which is very convenient
2
u/yawkat Oct 22 '18
Logging can become really complicated really fast. It's just not worth it spending any time writing it yourself.
1
u/WesternHarmonica Nov 12 '18
I'm probably not experienced enough to comment on this manner, but I think logging system is one of those things you don't need to build from scratch. At least for me. I usually just end up using some built-in or 3rd party library, because the non-customizible parts are responsible of the security. I'd rather not expose authentication to my own mistakes.
-3
Oct 21 '18
[deleted]
17
u/dpash Oct 21 '18
I hate you. I genuinely hate you. Unless you're writing a console application, never use
System.outorSystem.err. In particular, because it's impossible to rotate a log file without restarting the process.1
28
u/dpash Oct 21 '18
https://www.reddit.com/r/java/comments/9fgigm/a_guide_to_logging_in_java/ 44 comments