hiho guys i want to ask you for the best practice (according to you) for writing a log in different files, for example i want info severity to be logged in info.log, debug severity in debug.log and so on... and no i dont want to use different Logger for each severity
We had an application that used to do this (separate log files per severity), and it ended up providing us no value.
All it ends up doing is A) complicating your debugging efforts, and B) taking up disk space.
Logging all severities to the same file is more convenient and easier to work with.
Related
I have a 3rd-party developed big complex application full of java.util.logging.Logger#finer() calls.
Normally I use log4j and sl4j for logging, and I don't know very much of java.util.logging, even less about all the configuration details and possibilities.
Every single google about "java.util.logging" points to a full explanation about streams handlers, formatters, levels. Everyone assumes I really care about all this stuff (it is a reasonable assumption actually). But I couldn't care less.
I'm not really interested in separating logs per file, or file rotation, zipping, email, remote log etc. I'm also not concerned about log level and message formatting thrills.
All I want to do is to run this application with all available log messages spitting to stdout.
Is there an easy simple direct way to do this?
Something like jvmargs -Djava.util.logging.level=FINEST -Djava.util.logging.to=stdout.
Or maybe some simple file dropped into some location in the classpath?
All I want to do is to run this application with all available log messages spitting to stdout
Don't do this in production but it is the fast, easy, hacky way:
Edit the logging.properties file located in java/conf. E.G. /usr/lib/jvm/default-java/conf/logging.properties
That file is setup to attach a ConsoleHandler to the root logger which is what you want to do this. You just need to adjust the levels to see the output. This is a global change so be aware.
Edit that file and:
Change .level= INFO -> .level=ALL
Change java.util.logging.ConsoleHandler.level = INFO to java.util.logging.ConsoleHandler.level = ALL
Save the changes and restart your app.
The recommended way:
Most JVMs are not in your control (production/dev server) so you can instead copy that file to a location you own and use the java.util.logging.config.file system property.
E.G. -Djava.util.logging.config.file=/home/myuser/myapp/logging.properties
That way you are free to make changes that are local to your program and not global to the machine.
Why is it a good practice to use logger.debug() instead of System.out.println()?
I understand that log4j allows you to control what you wish to print (DEBUG,FATAL,INFO, etc), but apart from that, is there any other benefit?
A Logger adds so much more value to your logging.
Log levels: In a production environment you don't care about some levels (ex: debug info), only serious errors and system crashes.
Log filtering: Filter what components are allowed to log.
Log formatting: Control the information and its format contained in the log. You can setup defaults (like time and thread id) or add more specific ones per statement.
The log destination: You can set up your logger to write to a file, to emails, to databases, etc.
A policy for keeping and archiving logs: Let the logger manage the logs, keep some history, delete older
Also, Loggers are usually synchronized, so your print statements aren't written over eachother. You cannot guarantee that with System.out.
You can implement all this with System.out, but it would be so complex and tedious.
If your code is ever used in a web service or a system service, using debug statements will ensure that they appear in the services logs. If not you risk them being printed to a hidden console window and being lost.
Specialized loggers offer a number of benefits over plain standard output:
logical separation of logging, in at least two orthogonal areas: subsystem and importance
flexibility - there are many predefined ways to output and store log data, and you can roll you own, if you really want
configurability - you can precisely control what and where to log, and all of this is external to the code that actually uses logging, making it simple and inobtrusive
formatting - you don't need to manually append all the bookkeeping information, such as the class name, time etc. Logger does that for you, in an entirely configurable way, allowing you to write simple, clear logging code and retain all the benefits, like filtering and precise information.
speed - loggers are optimized not to introduce much overhead
I am using slf4j+log4J in Spring.
I want to store logs in different files based on log levels and also in one common file,so that I will first check this common log file and later review individual level logs files.
In short all level logs in one log file and then individual level logs in individual files.
Please guide me how to do this?
Also ,suggest suitable purpose of the levels keeping live projects in view.like where to use info,debug etc.
It should be straight forward. I am not giving the config directly but I think it should be easy for you to figure out the real config.
First, in the root logger (or the parent logger you want), point to several appenders, e.g. FILE_ALL, FILE_ERROR, FILE_WARN etc
Then declare FILE_ALL as normal file appender, which accept log event of all levels.
For other "level-specific" appender, it is still a normal file appender, PLUS a filter config. You may make use of LevelMatchFilter and declare the "level to match" as the corresponding level of the file.
In apache-tomcat are there any performance benefits of using some logging framework like log4j or java.util.logging over printing to stdout which gets dumped to catalina.out (which is the default behavior)?
Functionally both are same for my use-case since I don't need any extra formatting for logged messages.
I would like to know the benefits of using a logging framework here.
Thanks in advance!
You won't see performance benefits, from that perspective just go with whatever provides your functionality.
Adding something like log4j is so easy anyway though, and provides so much more future flexibility, that I'd never even think of relying on stdout for a webapp output, no matter how limited my current requirement.
Edit: it's not just formatting of messages, stuff like including class-that-wrote-the-log-entry, line of code, thread name, etc - all of these can be included in logs "free" once you're using a logging framework, and they're just not available with stdout.
besides formatting there are many advantages to using logger instead print to console. And perfomance too. For example you can simple switch before log levels to achive better perfomance. You can achive additional perfomance when use right logger like logback.
For example logback has feature use placeholders in log message
log.debug ("Result of big function = {}", bigAndLongMethod())
this will be faster then
log.debug("Result of big function = " + bigAndLongMethod())
because in first case bigAndLongMethod() willn't be executed if your loglevel higher then debug.
Using some additional appenders can increase perfomance to, i.e. redirect log to other host or log into db.
As additional benefit you will get more standart-comliant log support in you project, and you be more sotisfacted with it in future, even you don't see any difference right now.
I want to log information to a file and want to know is there any advantage in using the Java Logger class versus my own personal method of logging?
I know using a logger I just add my own FileHandler to the logger. My personal method is just using a FileOutputStream.
Honestly your logger may be as good, it's pretty easy to put in log levels, filtering, etc.
The problem is when you start to put together code from 10 different groups each with their own logging. Some use System.out, some use some custom logger, some use log4j, ...
How do you parse or redirect the output? How do you filter all that output to just show your messages (For instance, filtering options in log4j won't prevent messages being sent straight to System.out).
It's a pretty big bulk change depending on which system you are moving from/to. Better just to use one very common one from the beginning and hope that it's the one everybody else on the project chooses.
The real question is: why would you bother writing your own logger when there are already existing libraries for doing that? Does your logger do something that the others don't? I kind of doubt it.
Standardization is another big issue - see Bill K's answer.
For most scenarios, a standard logging framework is the way to go. They are pretty flexible. But using your own implementation can also be a valid option, specially if we are not speaking of traditional logging (global debugging, problems, warning messages) but about specific informational meesages or accounting.
Among other factors, bear in mind that the standarization of logging allows third party libraries to cooperate. For example, if you have a standard web application using (say) Hibernate, and you have configured a standard Java logging lib, then you can not only log from your own code but also tell Hibernate to log debugging info to your log files (not necessarily the same files). That is very useful - almost a must.
If you code your own logging library with a plain FileOutputStream, you must decide -among other things- if you are going to keep the file opened, or reopen-append-close in each write - and you must take of synchronization and related issues. Nothing terribly complicated, though.
The logger gives to ability to define different levels of importance of the logged messages and the ability to use different sink for the output - the console, a file, etc.
Also it's easy to enable or disable only some type of message when using a logger - for example you don't want to see every debug message in production.
A logging framework allows you specify logging levels (e.g. log only critical messages, log only debug messages etc.). It also allows you to log to multiple destinations (e.g. to a file, to syslog etc.) and you can do this even after your application is fully built by just changing a config file and not changing any code. It can also format your logs easily depending on various parameters.
There are numerous other advantages since proper logging is a rather involved problem and these packages have been written to solve them. I think the important question, why would you not use them?
Well I would always prefer tested thing and approved by community over something which still need a lot of test. Logger allows you many things which will consume you some time to implement and to test the robustness of your solution. A big plus will be the know-how of the next person who will do something with your code, in case it will be your logger, normally it would take more time to learn how its working out, since there is much more examples and documentation for java.util.logger.
Like all others mention, there are more advantages to using a more common logging system over writing your own. To be honest, the Java util logging api is not nearly as extensive and configurable as other libraries you might find out there on the internet.
Bare in mind that rolling your own always has the disadvantage of being less tested and therefore more prone to break or skip some potentially crucial messages.
Personally I prefer using SLF4J since it allows me to plug in adapters for more commonly used logging frameworks and then let's me pick my own actual logging implementation, this solves most of the problems with different library writers preferring different logging frameworks. And if you consider yourself up for the task you could writer an implementation for SLF4J yourself ;)