Before开发者_JAVA百科 I reinvent the wheel - I want to be able to insert debugging traces in my code, such as say("We are here.");
, without defining static void say()
in every class. It needs to do System.out.println(s)
, and to be globally switched on or off (doSay(false)
), and I'd also like it to be able to identify the class from which it's being invoked (as described here). For example:
MyClass: We are here.
Does Java already have such a tool?
Use SLF4j, not log4j (at least, not directly). They are both created by the same author, Ceki Gülcü, but SLF4J incorporates knowledge gained by seeing log4j in use, and looking at advances in other logging packages.
SLF4J is a common API for a number of different underlying logging systems, like log4j, the java.util.logging
package, etc. It also has its own "native" implementation, logback.
One reason I like it better than log4j is its support for message templates. These keep your code simpler.
Also, it allows me to include logging in a library, but let the user of my library choose the logging implementation. Without something like this, a user might have to configure logging just for my library, and it wouldn't be unified with the rest of his application.
The most popular Java logging framework is Log4J which does this (and much more).
Look here for a list of other.
Yes. It's called a logging framework. Java has java.util.logging
. But many prefer using Log4J.
You could use a logger like Apache's Log4J and do something like logger.trace("We are here");
. When you want that off, set the log level higher (debug, warn, error) in your configuration and the trace
logs will disappear.
Java has more advanced logging tools, like log4j or logback. There you should create a public static final Logger logger = Logger.getLogger(..)
and use the logger to write debug/info/warn/error messages to wherever you like. They are highly configurable - what and where to log.
For the simpler case (if this is a toy project), you can simply define a class with the public static void log(..)
method and use it from every class.
Why not static-declare a function in your Main.java, and use it allround?
public class Main {
private static boolean debug;
public static void setDebug(boolean d) { Main.debug = d; }
public static void say(String s) { if(Main.debug) System.out.println(s); }
}
Let me know if this fits your needs.
Edit: revised the code
I didn't know about static import! I combined ideas from @ninetwozero, @karl, and @erickson to create this:
package myPkg;
public class CLHUtilities {
private static boolean saying = false;
public static void tracing(boolean b) {
saying = b;
}
/*
* Technique taken from:
* http://stackoverflow.com/questions/282977/which-class-invoked-my-static-method
*/
public static void say(String s) {
if (saying) {
Throwable t = new Throwable();
StackTraceElement[] trace = t.getStackTrace();
String className = trace[1].getClassName();
String whoCalledMe = null;
try {
whoCalledMe = Class.forName(className).getSimpleName();
} catch (Exception e) {
}
System.out.println(whoCalledMe + ": " + s);
}
}
}
which can be used simply as:
import static myPkg.CLHUtilities.*;
:
tracing(true);
:
say("We are here.");
Which suits my needs perfectly.
精彩评论