How do you reduce Java logging boilerplate code?
Every class that wants to use java.util.logging generally needs to declare a logger like this:
public class MyClass {
private static Logger _log = Logger.getLogger(MyClass.class.getName());
}
How do you avoid this MyClass.class.getName() boilerplate code?
Asked by: Dexter685 | Posted: 21-01-2022
Answer 1
I have a template set up in Eclipse so that I only have to type a portion of the declaration, and then Eclipse will auto-complete the rest for me.
${:import(org.apache.log4j.Logger)}
private final static Logger log = Logger.getLogger(${enclosing_type}.class);
${cursor}
So, I only have to type logger
, hit Ctrl+Space
, followed by Enter
, and Eclipse fills in the rest for me and adds the import declaration as well.
This won't cut down on the amount of boilerplate code, but at least it cuts down on the amount of keystrokes.
Answered by: Chelsea276 | Posted: 22-02-2022Answer 2
Have a look at using point cuts in your code
I have not looked back since using them with spring.
Here is an article on using AspectJ
http://www.developer.com/java/other/article.php/3109831
Answered by: Haris889 | Posted: 22-02-2022Answer 3
Depending on your logging needs, you could create a "LoggingService" class with static methods for logging to various "channels". I have found that I really don't need logging granularity down to the class level. You can name your loggers what every works best for you. We have been using this in large, enterprise applications for several years and the granularity has really not been an issue for us.
The logging service initialized in a static initializer block...so to log a message:
LoggingService.logError("blah");
No boilerplate code in each class.
Here is an example logging service:
public class LoggingService {
/**
* A log for informational messages.
*/
static private Logger infoLog;
/**
* A log for data access messages.
*/
static private Logger dataAccessLog;
/**
* A log for debug messages.
*/
static private Logger debugLog;
/**
* A log for error messages.
*/
static private Logger errorLog;
/**
* A log for all XML related messages.
*/
static private Logger xmlLog;
/**
* A log for all trace messages.
*/
static private Logger traceLog;
/**
* A log for all warning messages.
*/
static private Logger warnLog;
static {
//This is the bootstrap for the logging service.
//Setup each logger
infoLog = Logger.getLogger("com.company.logging.info");
dataAccessLog = Logger.getLogger("com.company.logging.dataaccess");
debugLog = Logger.getLogger("com.company.logging.debug");
errorLog = Logger.getLogger("com.company.logging.error");
xmlLog = Logger.getLogger("com.company.logging.xml");
traceLog = Logger.getLogger("com.company.logging.trace");
warnLog = Logger.getLogger("com.company.logging.warn");
// This must be set so isErrorEnabled() will work.
errorLog.setLevel(Level.ERROR);
warnLog.setLevel(Level.WARN);
}
static public void logDataAccess(String pMessage) {
dataAccessLog.info(pMessage);
}
static public void logInfo(String pMessage) {
infoLog.info(pMessage);
}
static public void logDebug(String pMessage) {
debugLog.debug(pMessage);
}
static public void logTrace(String pMessage) {
traceLog.debug(pMessage);
}
static public void logWarn(String pMessage) {
warnLog.warn(pMessage);
}
static public void logError(String pMessage) {
errorLog.error(pMessage);
}
static public void logError(String pMessage, Throwable pThrowable) {
errorLog.error(pMessage, pThrowable);
}
static public void logXml(String pMessage, XmlBean pContainer) {
if (!xmlLog.isInfoEnabled()) return;
xmlLog.info(pMessage + " : " + JAXBHelper.marshal(pContainer));
}
static public boolean isInfoEnabled() {
return infoLog.isInfoEnabled();
}
static public boolean isDataAccessEnabled() {
return dataAccessLog.isInfoEnabled();
}
static public boolean isDebugEnabled() {
return debugLog.isDebugEnabled();
}
static public boolean isErrorEnabled() {
if (errorLog.getLevel().toInt() >= Level.ERROR_INT) {
return true;
}
return false;
}
static public boolean isTraceEnabled() {
return traceLog.isDebugEnabled();
}
static public boolean isXmlEnabled() {
return xmlLog.isInfoEnabled();
}
static public boolean isWarnEnabled() {
return warnLog.isEnabledFor(Level.WARN);
}
}
Answered by: Daryl443 | Posted: 22-02-2022Answer 4
Actually, the common practice of using class names for logger names is lazy more than anything.
The much better practice is to name loggers by the task context. This involves somewhat more thought process and planning but in the end, the result is much more meanigful granularity, where you can toggle logging levels for actual tasks rather than classes.
Answered by: Ned909 | Posted: 22-02-2022Answer 5
You don't need getName() if you're using a 1.2+ version of log4j, getLogger() accepts a Class argument. But as for the rest, there isn't any way around it if you want each class to have a static log member with its own category.
Answered by: Maddie793 | Posted: 22-02-2022Answer 6
If you go for package-level loggers, with the addition of a boilerplate class per package, you can write:
private static final Logger log = Logs.log;
There are hacks to read the class name of the caller (in fact the logging implementation has a hack to detect the current method), but I wouldn't recommend that.
Answered by: Roland116 | Posted: 22-02-2022Answer 7
You can reduce that and many other boilerplate codes with lombok
https://github.com/rzwitserloot/lombok
@Slf4j
public class LogExample {
}
will be
public class LogExample {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
}
Answered by: Walter120 | Posted: 22-02-2022
Answer 8
You can shorthand this a tiny bit, as getLogger is overloaded to also just take the class. Like so:
public class MyClass {
private static Logger _log = Logger.getLogger(MyClass.class);
}
The Logger can be as fleixble or inflexible as you want it to be. You can grab a new logger for each class, as in your example above, and have a hierarchy of loggers where you can controll and turn on/off the logging by class. Or if your project is small or a prototype, etc, you could just call Logger.getRootLogger() - but you'll lose the flexibility of fine-tuning what you log and don't log. You could have a base class where the logger lives, and have everyone call that one, but again, you lose some flexibility:
public class MyBase {
protected static Logger _log = Logger.getLogger(MyClass.class);
}
public class MyClass extends MyBase {
....
_log.info("Stuff....");
}
Bottom line, if you want to keep the ability to fine-tune configure your logging later in the project (turn on finer level debugging for just one class), then you may have to stick with the boilerplate in every class.
Answered by: Lucas862 | Posted: 22-02-2022Answer 9
Take a look at SLF4J
Answered by: Sawyer649 | Posted: 22-02-2022Answer 10
If you make the logger nonstatic, you can at least inherit it:
public class SomeBaseClass
{
protected Logger logger = Logger.getLogger(getClass());
}
public class SubClass extends SomeBaseClass
{
public void doit() { logger.debug("doit!!!!"); }
}
That's how I've always done it.
Answered by: First Name331 | Posted: 22-02-2022Similar questions
c# - Which languages have support for return value caching without boilerplate code?
For methods where ...
there exists a static one-to-one mapping between the input and the output, and
the cost of creating the output object is relatively high, and
the method is called repeatedly with the same input
... there is a need for caching result values.
In my code the following result value caching pattern is repeated a lot (pseudo-code in Java, but the questi...
java - Remove boilerplate from db code
It seems that every time I want to perform a db query, I have to write the following:
Connection conn = null;
Statement stmt = null;
ResultSet rset = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
// ...set stmt params
rset = stmt.executeQuery();
while(rset.next()) {
// Do something interesting
}
} finally {
try { if (rset != null) rset...
How to prevent boilerplate Java code on parsing a complex XML file?
I have written a XML parser with DocumentBuilderFactory for a complex XML file. Because there are many different node types that there are many boilerplate code. For every node type (NodeName) I have a loop over the children and a switch for the possible children elements.
Is it possible only to register the needed code for the different node types and then run the parsing?
java - Swing thread safety boilerplate
For the sake of simplicity, imagine an application that downloads a file. There is a simple GUI with one label that displays progress. To avoid EDT violations, like every lawful citizen I download the file in one thread (main), and update GUI in another (EDT). So, here's the relevant chunk of pseudcode:
class Downloader {
download() {
progress.startDownload();
while(hasMoreChunks()) {
...
dry - Is there a way to implement the Forwarding Object pattern in Java without boilerplate code?
Since encapsulation is considered better than inheritance (according to Effective Java and other sources), there is a pattern of Forwarding an Object. (I believe the Decorator pattern is a synonym for this, but please don't yell at me if I'm wrong!)
Basically, you write code like this:
class public ForwardSomething extends Something {
private Something something=new Something();
public void s...
java - What is Boilerplate code, Hot code and Hot spots?
I know these terms are used in context of performance achievement/optimization.
Recently have been working on that, and have tried searching; but didn't get any example, which clearly elaborate/describe these concepts with the realization of these problems/concepts in real world development scenarios.
Can somebody please thoroughly explain these terms, example scenarios, and where these concepts and term...
Using the Java Class object in boilerplate code
On occasion, as much as I try to avoid it, I do generate a fair amount of boilerplate code in my programming. I've been told that the Java Class object can be used to get around boilerplate code, but I don't currently see how.
When I say boilerplate code, I'm referring to the term used to refer to text that is reused again and again, with slight modification.
public Map<String, Boolean> loadBo...
java - How to automate Hibernate boilerplate in RMI remote methods
I have an RMI class that accepts remote calls from clients.
This class uses Hibernate to load entities and perform some business logic, in general read-only.
Currently most of the remote methods bodies look like that :
try {
HibernateUtil.currentSession().beginTransaction();
//load entities, do some business logic...
} catch (HibernateException e) {
logger.error("Hibernate probl...
java - Is there a way to generate boilerplate code for RESTful stacks?
As I get more into RESTful APIs, the (good) simplicity of the approach means that you generate a LOT of boilerplate code, and code that has to match in three or four different places, e.g. for a Jersey-based stack:
HTML on the web page which provides controls (a button Create Foo)
JS on the web page which formulates the JSON and the request to create a Foo
A FooRest...
java - Removing boilerplate testing code with @Rule
I'm writing tests right now and am realizing that they're all pretty similar in the beginning:
@Test
public void testThisMemoryOperation() {
Assert.assertEquals("Sanity check failed, shouldn't be anything in memory yet.",
0, memoryManager.getObjectsInMemory());
/* ... */
}
@Test
public void testThatMemoryOperation() {
Assert.assertEquals("Sanity check failed, shouldn't be anything i...
Still can't find your answer? Check out these amazing Java communities for help...
Java Reddit Community | Java Help Reddit Community | Dev.to Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)