I am beginner of java
I am making some program with excel(poi)
and I've been trying to use log4j2
to log what is wrong when run jar or exe
so I got a question
when I searched how to use log4j2 on internet
there is only a usage which like
try{some method}
catch(exception ex)
{logger.catching(ex)}
is it the only way to log ?
is there a way to log without using try catch?
for now ,I think if I use try and catch
I need to use a lot of try catch or throws..
thank you in advance!
Sure. You can invoke logger.whatever() anywhere. E.g. logger.info(); Method catching() is used to log an exception or error that has been caught. That's why in your example it's used with try-catch block. Read more in docs.
Yes, you can log things other than exceptions. In fact you can log anything you want. Please see the log4j2 manual, in particular the page called Java API
You simply create your logger and invoke one of the methods specific to the level you want for your event, or if you're using a custom level use the log method. See the architecture page of the manual for more on log levels.
The code below is from the Java API page of the manual and shows you how to log the message "Hello, World!" at INFO level.
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class HelloWorld {
private static final Logger logger = LogManager.getLogger("HelloWorld");
public static void main(String[] args) {
logger.info("Hello, World!");
}
}
Related
For comparison, android has a kick-ass logger, where in one line I can do
Log.d("TAG", "Something important is happening here.");
Using eclipse on app engine, I have been doing
private static final Logger LOG = Logger.getLogger(MyClass.class.getName());
…
//inside method
LOG.info("I don’t want to have two lines");
I am moving to android studio, is there a way to do something as cool as the one on android? I imagine I might have to add a dependency to Gradle. Any ideas how I might do this?
Not sure what you're asking. How is your logging dependent on your IDE?
But to answer your question: When using Java on AppEngine you should use java.util.logging. Only java.util.logging logs will go into the Monitoring -> Logs section of your cloud console. We're using slf4j in our projects, which is nice if you have multiple projects with different logging mechanisms but what to use the same syntax.
Actually, you could also use a different logger and write the logs to System.out but i don't recommend it. You should use the facilities App Engine provides.
If you must, you could do something similar as you have in Android Studio. That would probably work with a static import of a Log class and a lot of reflection / stack unwinding to get the logging class name. Since reflection is the opposite of performance, i wouldn't do that.
Unfortunately no, the Log you mention (the cool one) is part of the Android framework and it's independent of your IDE.
You could build your own log "utils" and either extend it or call it statically to reduce logging code.
eg.
public class LogAware {
protected void log(Level level, String message){
Logger.getLogger(this.getClass().getName()).log(level,message);
}
protected void logInfo(String message){
log(Level.INFO,message);
}
protected void logFine(String message){
log(Level.FINE,message);
}
protected void logWarning(String message){
log(Level.WARNING,message);
}
protected void logSevere(String message){
log(Level.SEVERE,message);
}
protected void logException(Exception e){
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE,"Exception Thrown",e);
}
I am learning the LibGDX engine in parallel to re-learning java, and have written a simple logging class that has one method with a string argument to be passed to the Gdx.app.log(). while this isn't needed I did so to practice importing and using custom methods and classes, as well as reducing the length of the line needed to send a message to the console. the method looks like so:
import com.badlogic.gdx.Gdx;
public class logging {
public static final String tag="Console";
//contains method for logging to the console during testing.
public void log(String message){
Gdx.app.log(tag, message);
}
}
Then in the class I am using it in, it is imported properly, and a public logging 'con' is created. Up to this point everything seems to work fine because when I type con. in eclipse I get the log(message) as an autocomplete option, however when it is actually called for instance in a screen, under the show() method. when the program tries to step through that point i get a java.lang.NullPointerException which is confusing the hell out of me since everything is written properly. as an example of its use:
con.log("this is a test");
is the exact usage I attempt which seems fine in eclipse before runtime. Is there some simple idea I am failing to grasp here? or a quirk to the Gdx.app.log()? Please no responses with "just use the Gdx.app.log(); where you need to write to the log" as this is not the point of the exercise for me. thank you in advance for all the help!
If you are getting a NullPointerException in this line:
con.log("this is a test");
The only thing that can be null is con. You are probably defining it, but not actually creating it.
Logging con;
and not
Logging con = new Logging();
In a large project we have something like:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
class Test {
static final Log logger = LogFactory.getLog(Test.class);
public void execute() {
log.info("writing some info");
log.error("writing some error");
}
}
I know that as it runs:
I am using
class org.apache.commons.logging.impl.Log4JLogger
Because I am able to connect remotely and put a breakpoint on my debug and see what class it is.
how can I figure out what log configuration is using ?
where is it picked up from ?
how is it configured ?
p.s.
Note the app. is actually quite complex and it's running within web logic app server. I don't have access to all its java code.
p.s.II
My idea would be to inject some code inside the execute method to determine where the heck log4j.properties is , if it is there at all and so on...
I have methods that are defined as...
public static void myMethod throws IOException ....
how can I use the Logger class to log the exception that is thrown to a file say named "test.log". I've heard of using logger.throwing... but it doesn't seem to work. Could anyone give me a step by step tip on how to do this? I just basically need to log the exception that is thrown (I didn't use try catches). Thank you so much!
You'll need to add a catch clause. Below is a start for using the java.util.logging.Logger. Note that many projects use an Apache logger which is a bit more powerful and more complicated. Let's say you have a class com.myCompany.Foo that reads some file stuff
typically, at the start of the class in the static field declarations you will have
private static final Logger LOGGER = Logger.getLogger("com.myCompany.Foo");
then, when you have a method that throws exceptions (this is a stupid method!)
int readFirstCharOfFile(File f) throws IOException {
FileReader reader = null;
try {
reader = new FileReader(f);
return reader.read();
}
catch (IOException ioe) {
// You have a lot of possibilities here, but this seems most reasonable
LOGGER.log(Level.SEVERE, ioe.getMessage(), ioe);
// whether you rethrow the Exception "depends" on the contract, but, in our case
// the method declaration says that we do, so we do.
throw ioe;
}
finally {
if (reader != null)
reader.close();
}
}
The harder part is configuring the Logger to write where you want. IIRC, by default it goes to standard error. There is a lot of "magic" there that I never fully understood so I couldn't explain all the intricacies.
You can Google to get info, here are a couple useful links I found. link1 and link2
If you want a more automatic approach than the one given by user949300, you could take a look at Aspect-Oriented Programming (AOP), which allows you to do exception logging for all methods with just a little bit of code. Just google for aspectj log exceptions or java aop log exceptions.
See also question Audit Java: system to detect exceptions thrown / caught (aop?)
Try to use jcabi-aspects and its #LogException annotation:
public class Resource {
#LogExceptions
public String load(URL url) {
return url.openConnection().getContent();
}
}
How can I detect when an Exception has been thrown anywhere in my application?
I'm try to auto-magically send myself an email whenever an exception is thrown anywhere in my Java Desktop Application. I figure this way I can be more proactive.
I know I could just explicitly log and notify myself whenever an exception occurs, but I'd have to do it everywhere and I might(more likely will) miss a couple.
Any suggestions?
You probobly don't want to mail on any exception. There are lots of code in the JDK that actaully depend on exceptions to work normally. What I presume you are more inerested in are uncaught exceptions. If you are catching the exceptions you should handle notifications there.
In a desktop app there are two places to worry about this, in the event-dispatch-thread (EDT) and outside of the EDT. Globaly you can register a class implementing java.util.Thread.UncaughtExceptionHandler and register it via java.util.Thread.setDefaultUncaughtExceptionHandler. This will get called if an exception winds down to the bottom of the stack and the thread hasn't had a handler set on the current thread instance on the thread or the ThreadGroup.
The EDT has a different hook for handling exceptions. A system property 'sun.awt.exception.handler' needs to be registerd with the Fully Qualified Class Name of a class with a zero argument constructor. This class needs an instance method handle(Throwable) that does your work. The return type doesn't matter, and since a new instance is created every time, don't count on keeping state.
So if you don't care what thread the exception occurred in a sample may look like this:
class ExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
handle(e);
}
public void handle(Throwable throwable) {
try {
// insert your e-mail code here
} catch (Throwable t) {
// don't let the exception get thrown out, will cause infinite looping!
}
}
public static void registerExceptionHandler() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
System.setProperty("sun.awt.exception.handler", ExceptionHandler.class.getName());
}
}
Add this class into some random package, and then call the registerExceptionHandler method and you should be ready to go.
The new debugging hooks in Java 1.5 let you do this. It enables e.g. "break on any exception" in debuggers.
Here's the specific Javadoc you need.
Check out Thread.UncaughtExceptionHandler. You can set it per thread or a default one for the entire VM.
This would at least help you catch the ones you miss.
If you're using a web framework such as Spring then you can delegate in your web.xml to a page and then use the controller to send the email. For example:
In web.xml:
<error-page>
<error-code>500</error-code>
<location>/error/500.htm</location>
</error-page>
Then define /error/500.htm as a controller. You can access the exception from the parameter javax.servlet.error.exception:
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
If you're just running a regular Java program, then I would imagine you're stuck with public static void main(String[] args) { try { ... } catch (Exception e) {} }
If you are using java 1.3/1.4, Thread.UncaughtExceptionHandler is not available.
In this case you can use a solution based on AOP to trigger some code when an exception is thrown. Spring and/or aspectJ might be helpful.
In my current project I faced the similar requirement regarding the errors detection. For this purpose I have applied the following approach: I use log4j for logging across my app, and everywhere, where the exception is caught I do the standard thing: log.error("Error's description goes here", e);, where e is the Exception being thrown (see log4j documentation for details regarding the initialization of the "log").
In order to detect the error, I use my own Appender, which extends the log4j AppenderSkeleton class:
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class ErrorsDetectingAppender extends AppenderSkeleton {
private static boolean errorsOccured = false;
public static boolean errorsOccured() {
return errorsOccured;
}
public ErrorsDetectingAppender() {
super();
}
#Override
public void close() {
// TODO Auto-generated method stub
}
#Override
public boolean requiresLayout() {
return false;
}
#Override
protected void append(LoggingEvent event) {
if (event.getLevel().toString().toLowerCase().equals("error")) {
System.out.println("-----------------Errors detected");
this.errorsOccured = true;
}
}
}
The log4j configuration file has to just contain a definition of the new appender and its attachement to the selected logger (root in my case):
log4j.rootLogger = OTHER_APPENDERS, ED
log4j.appender.ED=com.your.package.ErrorsDetectingAppender
You can either call the errorsOccured() method of the ErrorsDetectingAppender at some significant point in your programs's execution flow or react immidiately by adding functionality to the if block in the append() method. This approach is consistent with the semantics: things that you consider errors and log them as such, are detected. If you will later consider selected errors not so important, you just change the logging level to log.warn() and report will not be sent.
In this case I think your best bet might be to write a custom classloader to handle all classloading in your application, and whenever an exception class is requested you return a class that wraps the requested exception class. This wrapper calls through to the wrapped exception but also logs the exception event.
I assume you don't mean any Exception but rather any uncaught Exception.
If this is the case this article on the Sun Website has some ideas. You need to wrap your top level method in a try-catch block and also do some extra work to handle other Threads.
Sending an email may not be possible if you are getting a runtime exception like OutOfMemoryError or StackOverflow. Most likely you will have to spawn another process and catch any exceptions thrown by it (with the various techniques mentioned above).
There is simply no good reason to be informed of every thrown exception. I guess you are assuming that a thrown exception indicates a "problem" that your "need" to know about. But this is wrong. If an exception is thrown, caught and handled, all is well. The only thing you need to be worried about is an exception that is thrown but not handled (not caught). But you can do that in a try...catch clause yourself.