While writing a very simple multi-platform console application in Netbeans, I have noticed a consistent warning at the statements System.out.println() and System.err.println(), which states these are often temporary debugging statements.
And in details on Netbeans wiki here, it states
These are often temporary debugging statements, and should probably be
either removed from production code, or replaced by a more robust
logging facility.
Why is it like this and what should I be using then to print out messages to the user strictly in console application viewpoint.
I am using several of these statements to inform user like, the argument is not valid, or some access denied exception occurred, etc.
Any suggestions would help.
If your application will be updated and/or will become a part of another more complex system, these System.out and System.err calls will become less convenient than a properly implemented logging subsystem in your application.
And it will be necessary to rewrite these parts of code to provide the more consistent logging picture for an administrator/end-user.
Related
I'd like to find redundant blocks of code in my service. Is there a way to check when that last time this code was used runtime? The service is running on GCP.
I don't think there's a great solution to your problem but you could instrument, perhaps via Aspect-Oriented Programming (AOP), selected places in your code with simple logging statements and then monitor those.
You should avoid including any "hot code" which is executed very frequently because you can slow down your service and produce an overwhelming amount of logs (harder to manage and costly).
There's a lot of way to do this, but personally, I would use logging into this function and then let this app running normally. Then, you'll just have to check you log files and check for your logging message occurrences.
However, I'm not sure if it is possible to get this information without any action of your part to see previous usages of your code block.
I use log4j in my application. In development I use tons of logger.debug to display infomation for debugging. I know I can make these verbose displays go away by changing the logging level in the configuration file when deployed, my questions is will this affect performance? Is it that although the debug level is disabled, the logging work is still there and dose something silently? Is it better to remove all the logger.debug codes in the final deploy version if performance is important?
Modern loggers very quickly return from an inactive logging statement for this very reason
You need to be aware of the price of constructing the string to be logged. If you use slf4j as the front end, use {} to delay this until after the tests
Any IO operation will affect performance. Even if you change logging level, each time you call log.debug, logger have to make decision to print message or not. However, making decision is faster than doing it with writing to file/console/something else.
In my application, I am running my code through PMD.It shows me this message:
Avoid printStackTrace(); use a logger call instead.
What does that mean?
It means you should use logging framework like logback or log4j and instead of printing exceptions directly:
e.printStackTrace();
you should log them using this frameworks' API:
log.error("Ops!", e);
Logging frameworks give you a lot of flexibility, e.g. you can choose whether you want to log to console or file - or maybe skip some messages if you find them no longer relevant in some environment.
If you call printStackTrace() on an exception the trace is written to System.err and it's hard to route it elsewhere (or filter it). Instead of doing this you are advised using a logging framework (or a wrapper around multiple logging frameworks, like Apache Commons Logging) and log the exception using that framework (e.g. logger.error("some exception message", e)).
Doing that allows you to:
write the log statement to different locations at once, e.g. the console and a file
filter the log statements by severity (error, warning, info, debug etc.) and origin (normally package or class based)
have some influence on the log format without having to change the code
etc.
A production quality program should use one of the many logging alternatives (e.g. log4j, logback, java.util.logging) to report errors and other diagnostics. This has a number of advantages:
Log messages go to a configurable location.
The end user doesn't see the messages unless you configure the logging so that he/she does.
You can use different loggers and logging levels, etc to control how much little or much logging is recorded.
You can use different appender formats to control what the logging looks like.
You can easily plug the logging output into a larger monitoring / logging framework.
All of the above can be done without changing your code; i.e. by editing the deployed application's logging config file.
By contrast, if you just use printStackTrace, the deployer / end user has little if any control, and logging messages are liable to either be lost or shown to the end user in inappropriate circumstances. (And nothing terrifies a timid user more than a random stack trace.)
In Simple,e.printStackTrace() is not good practice,because it just prints out the stack trace to standard error. Because of this you can't really control where this output goes.
Almost every logging framework provides a method in which we can pass the throwable object along with a message. Like:
public trace(Marker marker, String msg, Throwable t);
They print the stacktrace of the throwable object.
Let's talk in from company concept. Log gives you flexible levels (see Difference between logger.info and logger.debug). Different people want to see different levels, like QAs, developers, business people. But e.printStackTrace() will print out everything. Also, like if this method will be restful called, this same error may print several times. Then the Devops or Tech-Ops people in your company may be crazy because they will receive the same error reminders.
I think a better replacement could be log.error("errors happend in XXX", e)
This will also print out whole information which is easy reading than e.printStackTrace()
The main reason is that Proguard would remove Log calls from production. Because by logging or printing StackTrace, it is possible to see them (information inside stack trace or Log) inside the Android phone by for example Logcat Reader application. So that it is a bad practice for security. Also, we do not access them during production, it would better to get removed from production. As ProGuard remove all Log calls not stackTrace, so it is better to use Log in catch blocks and let them removed from Production by Proguard.
i am currently working on a java application for some network monitoring tool. In my code i am supposed to use logging a lot. Since its a network management software, the information in logs is quite useful to the user hence its compulsory to use them. But now I am bit confused with what kind of logger method i should prefer. Right now i am using Logger.lop(...//...) since with its help we are also logging the class name and method so its becoming very easy for me (developers) to debug the code and find the error. But finally I am confused should i deliver it to the end user with the same logging mechanism??? Is it any harm to let your user know what kind of class is executing currently , in which method error has occured. I have seen many times in many product in exception handling stacktrace is used so normally we get class name as well. So is there is no problem to let enduser know what your class name and method is??
Before considering the security implications of it, consider the performance. In most logging systems, getting the actual classname and method name dynamically by the logging facility requires reflection and dramatically slows down the logging - usually a synchronous operation. My guess is that in a network monitoring application, you really don't want that.
If you're hard-coding the method name into the log message (either by making it part of the message or by the category), that's a different story. As a security person, I don't consider it to be that big of a deal - if your code is in Java, it can be reversed anyhow, so your code should operate in such a way that it would be secure even if the code was given away.
All that being said, you could either use a different logging configuration for development and production, or those fine-grained messages could go in debug, trace, etc. If you're using log4j, it's generally advisable to use isDebugEnabled to wrap any logging statements which include anything dynamically-calculated as those get calculated before the logging statement determines whether it's enabled.
log4j/logback/slf4j allow you to have different formats for different appenders. For development you can enable a console appender where you include the class name in the format, while for the end-users you can omit it (for a file appender)
It's worth mentioning that such logging is performance costly in Java, contrary to C++ where it is usually implemented with preprocessor. Fortunately, with log4j/logback you can switch it on and off — follow Bozho's advice.
I'm using the Enerjy (http://www.enerjy.com/) static code analyzer tool on my Java code. It tells me that the following line:
System.err.println("Ignored that database");
is bad because it uses System.err. The exact error is: "JAVA0267 Use of System.err"
What is wrong with using System.err?
Short answer: It is considered a bad practice to use it for logging purposes.
It is an observation that in the old times when there where no widely available/accepted logging frameworks, everyone used System.err to print error messages and stack traces to the console. This approach might be appropriate during the development and local testing phase but is not appropriate for a production environment, because you might lose important error messages. Because of this, in almost all static analysis tools today this kind of code is detected and flagged as bad practice (or a similarly named problem).
Logging frameworks in turn provide the structured and logical way to log your events and error messages as they can store the message in various persistent locations (log file, log db, etc.).
The most obvious (and free of external dependencies) hack resolution is to use the built in Java Logging framework through the java.util.logging.Logger class as it forwards the logging events to the console by default. For example:
final Logger log = Logger.getLogger(getClass().getName());
...
log.log(Level.ERROR, "Something went wrong", theException);
(or you could just turn off that analysis option)
the descriptor of your error is:
The use of System.err may indicate residual debug or boilerplate code. Consider using a
full-featured logging package such as Apache Commons to handle error logging.
It seems that you are using System.err for logging purposes, that is suboptimal for several reasons:
it is impossible to enable logging at runtime without modifying the application binary
logging behavior cannot be controlled by editing a configuration file
problably many others
Whilst I agree with the points above about using a logging framework, I still tend to use System.err output in one place: Within shut-down hooks. This is because I discovered that when using the java.util.logging framework log statements are not always displayed if they occur in shut-down hooks. This is because the logging library presumably contains its own shutdown hook to clean up log files and other resources, and as you can't rely on the order in which shutdown hooks run, you cannot rely on java.util.logging statements working as expected.
Check out this link (the "Comments" section) for more information on this.
http://weblogs.java.net/blog/dwalend/archive/2004/05/shutdown_hooks_2.html
(Obviously the other alternative is to use a different logging framework.)
System.err is really more for debugging purposes than anything else. Proper exception handling and dealing with errors in a manner that is more user-friendly is preferred. If the user is meant to see the error, use a System.out.println instead.
If you want to keep track of those errors from a developer's standpoint, you should use a logger.
Things written to System.err are typically lost at runtime, so it is considered a better practice to use a logging framework that is more flexible about where to output the message, so it can be stored as a file and analyzed.
System.err and System.out for non-console applications is only ever seen by the developer running the code in his or her IDE, and useful information may get lost if the item is triggered in production.
System.err.println and System.out.println should not be used as loggging-interface. STD-Output and STD-Error (these are written by System.out and .err) are for messages from command-line-tools.
System.err prints to the console. This may be suitable for a student testing their homework, but will be unsuitable for an application where these messages won't be seen (Console only store so many lines).
A better approach would be to throw an exception holding the message that would normally get sent to the console. An alternative to this would be use third party logging software which would store this messages in a file which can be stored forever.